分治法 —— 快速幂

何为快速幂

例如 a ^ b ,按正常情况下我们需要从1 开始迭代到 b ,若b是较小数据,那对程序的影响微乎其微,若b是上千的数据,从1遍历到 b 需要的时间非常大, 大大降低程序的性能!

快速幂采用分治的策略,一分为二, 二分为四,四分为八…
a ^ b =( (a ^2) ^ (b/ 2) ) * a ^ (b % 2) = (a ^ (b/2))^ 2 * a ^ (b % 2)
= ( a ^ (b/2) * a ^ (b /2) ) * a ^ (b % 2) … 接着不断的分治

例:
图片未加载请刷新
我们如何实现快速幂呢?有递归和迭代两种方式!

Code 递归 (非快速幂)

//非快速幂递归求 a ^ b
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int fun1(int a, int b)
{
    if (b == 1)
        return a;
    return fun1(a, b - 1) * a;
}
int main()
{
    int a, b;
    a = 7; b = 9;
    cout << "sum1: " << fun1(a, b) << endl;
    return 0;
}

图片未加载请刷新

Code 递归 (快速幂)

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int fun2(int a, int b)
{
    int t;
    if (b == 1)//递归结束
        return a;

   if (b % 2 == 0)
   {
       t = fun2 (a, b / 2);
       return t * t;
   }
   else {
    t = fun2 (a, b / 2);
    return t * t * a;
   }
}
int main()
{
    int a, b;
    a = 7; b = 9;
    cout << "sum2: " << fun2(a, b) << endl;
    return 0;
}

图片未加载请刷新

Code 迭代 (非快速幂)

//非快速幂迭代
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int main()
{
    int a, b;
    a = 7; b = 9;
    int sum1 = 1;
    for (int i = 0; i < b; i++)
        sum1 = a * sum1;
    cout << "sum1 : " << sum1 << endl;
    return 0;
}

图片未加载请刷新

Code 迭代 (非快速幂)

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int main()
{
    int a, b;
    a = 7; b = 9;
    int res = 1;
    while (b > 0)
    {
        if (b % 2 == 1) res = res * a;

        a = a * a;

        b = b / 2;
    }
    cout << "sum2:" << res << endl;
	return 0;
}

图片未加载请刷新

结语

总体来说快速幂的时间要比非快速幂的时间短,当然我测试的数据的b较小,大家可以自行测试较大的b数值,但最终的结果一定的是快速幂的时间短于非快速幂

一般比较大的指数级运算都会采用快速幂

©️2020 CSDN 皮肤主题: 岁月 设计师:pinMode 返回首页