Я сегодня выучил еще один алгоритм.У меня ушло два часа, чтобы понять его с перерывами.Я должен вздохнуть.Алгоритм действительно слишком силен,и он упрощает слишком много шагов.Слишком силен,слишком силен,слишком силен?
Прежде всего, давайте поговорим о том, какую проблему решает быстрое питание. Основная проблема состоит в том, чтобы решить проблему «невыносимых чисел» для компьютеров. Представьте себе сценарий. Если вас просят рассчитатьиз后三位的值, что бы вы сделали? Может быть, вы скажете так просто, независимо от того, является ли ваше решение сложным расчетом, умным расчетом или разумным расчетом. Пожалуйста, выслушайте меня подробно:
1. Жесткий расчет степенной функции
Жесткий код расчета с использованием функции pow выглядит следующим образом:
#include<cmath>
int main(){
long long int x;
x = pow(2,120);
cout<<x<<endl;
cout<<x%1000<<endl;
return 1;
}
// 打印
// -9223372036854775808
// -808
Ха, почему такой результат? Затем поговорим о размере типа данных int, подробнее см. в этой статье. В 64-разрядных компиляторах тип int обычно занимает 4 байта, а тип long long int — 8. За исключением первого бита символа, максимальный допустимый размер составляет,иЭто намного больше, чем это число, поэтому измученный компьютер не может его сосчитать, не говоря уже о том, как сосчитать его последние три цифры.
Давайте улучшим его, используя волну теоремы по модулю для оптимизации оптимизации
2. Теорема по модулю
Проблема в том, что результат умножения нескольких больших чисел, решаемый операцией по модулю, слишком велик (компьютер его не поддерживает) и не может принять последние несколько цифр. Это также первый раз, когда я услышал теорему по модулю. Прочитав ее, Я обнаружил, что это настоящая корова — это математическая теорема. Я не буду здесь вдаваться в подробности, подробнее см. в моей ==другой статье==, конкретное содержание теоремы по модулю:
(a + b) % p = (a % p + b % p) % p (1)
(a - b) % p = (a % p - b % p ) % p (2)
(a * b) % p = (a % p * b % p) % p (3)
a ^ b % p = ((a % p)^b) % p (4)
Просто посмотрите на (3) здесь,(a * b) % p = (a%p * b%p) % p, это здорово, по модулю произведение равно произведению по модулю каждого множителя, а дальше берется по модулю, что равносильно контролю числа до p-1 бит, количество вычислений супер мало, есть лес~
Код с использованием операции по модулю:
int main(){
long long int result=1;
// x = pow(2,120);
clock_t start_time = clock();
for(int i=0;i<120;++i){
result = result*2%1000;
}
result = result % 1000;
clock_t end_time = clock();
cout<<result<<endl;
cout<<"计算花费时间:"<<double(end_time - start_time)/CLOCKS_PER_SEC<<endl;
// start_time和end_time的差值计算的是 CPU 运行程序所花费的时钟单元数量,然后在除以CLOCK_PER_SEC(是:CPU 每秒有多少时钟单元数。)
return 1;
}
// 打印
// 576
// 计算花费时间3e-06
Эта скорость слишком 6, а результат все равно вычисляется. Математическая теорема действительно слишком сильна. Я всегда любил ее ?, хотя самый главный тест в жизни - это тест по математике.
Почувствуйте силу математических теорем, но достаточно ли этого? Теорема по модулю только контролирует данные в пределах определенного количества цифр, так что число можно вычислить, но это не упрощает количество вычислений (все равно в 120 раз) Лучше бы был алгоритм, упрощающий вычисление шаги. Как говорится, нет самого быстрого, есть только быстрее?, если есть сегодняшний герой, пожалуйста, сократите количество вычисленийалгоритм быстрого возведения в степеньПоявляется:
3. Интеллектуальный расчет алгоритма Fast Power
Когда я увидел объяснение этого алгоритма, я встал, как будто увидел новый мир, манящий меня, то есть алгоритм. Алгоритм действительно силен, он может упростить сложную проблему до маленьких задач и решать их в цикле, а скорость очень высока.
Ну, хватит ерунды, пиши по делу. Прежде всего, я пишу статьи, чтобы упражнять свои писательские способности и углублять свое понимание знаний.Может быть, мое объяснение неясно. Если вы не понимаете, вы можете прочитать справочную статью внизу статьи, написанную большим парнем.алгоритм быстрого возведения в степеньДля получения более подробной информации вы можете перейти, чтобы увидеть, если вам это нужно.
3.1 Что такое алгоритм быстрого возведения в степень?
Алгоритм быстрого возведения в степень, также известный как двоичное возведение в степень, может значительно сократить этапы вычислений и повысить скорость работы.маленькие хитрости, чтобы вычислить вовремя, в то время как расчеты грубой силы требуютвремя.
3.2 Описание алгоритма
Например, мы вычисляем:, что эквивалентно,в. Но когда n очень велико, объем вычислений очень велик, так называемый «экспоненциальный взрыв». Здесь мы можем упростить,, объем вычислений мал в одно мгновение, например:, расчет на 200 шагов меньше, 300 шагов..., эффективности нет.
Зная, что взятие квадрата может сократить количество вычислений, мы можем следоватьбинарныйпредставлять власть. Тогда давайте посмотрим на взаимосвязь между мощностью и двоичным числом или приведем пример для объяснения: Например:.
Вы обнаружили, что есть толькодвоичный битЕсли он равен 1, он будет умножен на него, а если равен 0, то будет пропущен. Таким образом, нам нужно только использовать метод преобразования из десятичного числа в двоичное (непрерывно делить остаток от 2 до тех пор, пока частное не станет равным 0), чтобы получить двоичное число, соответствующее степени. Если двоичная цифра равна 1, умножьте соответствующее число на результат и удвойте основание; если это 0, удвойте основание. Вы можете посмотреть на процесс деривации ниже, Это место немного запутанно, и вы поймете это, пройдя по нему.
# 1、指数(power)13 对一个二进制,底数(base)为3
13/2 = 6 余1 # base变成3*3=9 result=result*3,base=base*base
6/2 = 3 余0 # base变成9*9=81 base=base*base
3/2 = 1 余1 # base变成81*81=6561 result=result*3,base=base*base
1/2 = 0 余1 # base变成6561*6561 result=result*3,base=base*base
# 所以对应的二进制是 1101
# 2、对应计算代码 Python
def quick(base, power):
result = 1
b = power
while(b>0):
if b&1: # 相当于是if b%2 == 1: 为奇数
result = result * base
base = base * base
b >>= 1 # 相当于是 b = b/2 b取一半
print(result)
quick(3, 13)
# 打印
# 1594323
Вы думали, что это конец? Есть еще один шаг, быстрая мощность только сокращает количество вычислений, но не решает проблему вычисления последних трех цифр высокой мощности (таких как:). Вы можете подумать, что если вы добавите предыдущую операцию по модулю, это уменьшит число, и вы сможете вычислить результат.
Правильно, вот и все, алгоритм быстрого возведения в степень + теорема по модулю - идеальное совпадение cp, вот волна кода на С++:
#include<iostream>
#include<ctime>
using namespace std;
int main(){
long long int result=1;
int base = 2,power=120;
clock_t start_time = clock();
while(power>0){
if(power & 1){
result = result*base%1000;
}
base = (base*base)%1000;
power >>= 1;
}
result = result%1000;
clock_t end_time = clock();
cout<<result<<endl;
cout<<"计算花费时间:"<<double(end_time - start_time)/CLOCKS_PER_SEC<<endl;
cout<<"CPU每秒时钟数:"<<CLOCKS_PER_SEC<<endl;
return 1;
}
// 打印
// 576
// 计算花费时间:1e-06
// CPU每秒时钟数:1000000
Вау, я наконец закончила писать, у меня голова болит ?~
Суммировать:
Алгоритм действительно сильный, а эффективность очень высокая, мне он нравится, и я усердно работаю над его изучением~
Справочная статья: