[算法]高精度快速幂

一.简介

  快速幂的效率和普通乘法不会快太多,因为 “n=n*n”这个操作使得底的位数指数级增长,例如刚开始输入的底n为100,n=n*n执行了两次之后,n=10000,再执行一次之后n=100000000,n越大,n=n*n 消耗的时间越大。据我来看,快速幂的主要不是用于求精确数,主要计算结果对k取模的情况,由于对k取模,因此无论 n=n*n执行多少次 n都不会超过k,有取模操作的快速幂看这里(快速幂:https://www.cnblogs.com/ChaseMeng/p/12790776.html),下面给出求精确结果的快速幂。

二.代码(C++描述)

 1 /*高精度快速幂(c++描述)*/
 2 #include<iostream>
 3 #include<stack>
 4 #include<vector>
 5 #include<string>
 6 using namespace std;
 7 vector<int>result;
 8 vector<int>n;//底
 9 vector<int>t;
10 int m;    //指数
11 
12 void mul() {    //n*result
13     for (int i = 0; i < n.size(); i++) {    //先不处理进位
14         for (int j = 0; j < result.size(); j++) {
15             if (i + j < t.size()) {    
16                 t[i + j] += n[i] * result[j];
17             }
18             else {    
19                 t.push_back(n[i] * result[j]);
20             }
21         }
22     }
23     int flag = 0;
24     for (int i = 0; i < t.size(); i++) {//处理进位
25         t[i] = t[i] + flag;
26         flag = t[i] / 10;
27         t[i] = t[i] % 10;
28     }
29     if (flag != 0) {
30         t.push_back(flag);
31     }
32     t.swap(result);
33     t.clear();
34 }
35 void my_pow() {    //n*n(和mul函数一样,就是乘数改了一下)
36     for (int i = 0; i < n.size(); i++) {
37         for (int j = 0; j < n.size(); j++) {
38             if (i + j < t.size()) {
39                 t[i + j] += n[i] * n[j];
40             }
41             else {
42                 t.push_back(n[i] * n[j]);
43             }
44         }
45     }
46     int flag = 0;
47     for (int i = 0; i < t.size(); i++) {//处理进位
48         t[i] = t[i] + flag;
49         flag = t[i] / 10;
50         t[i] = t[i] % 10;
51     }
52     if (flag != 0) {
53         t.push_back(flag);
54     }
55     t.swap(n);
56     t.clear();
57 }
58 
59 void init_n(int tmp) {
60     while (tmp) {
61         n.push_back(tmp % 10);
62         tmp = tmp / 10;
63     }
64 }
65 void print_vector(const vector<int>&v) {
66     for (vector<int>::const_iterator it = v.end()-1; it != v.begin(); it--) {
67         cout << *it;
68     }
69     cout << *v.begin();
70     cout << endl;
71 }
72 int main() {
73     int tmp;//底数
74     cin >> tmp >> m;
75     init_n(tmp);//将底数放入数组n
76     result.push_back(1);//初始化结果为1
77     while (m) {
78         if (m & 1) {
79             //result *= n;
80             mul();
81         }
82         m = m >> 1;
83         //n *= n;
84         my_pow();
85     }
86     print_vector(result);
87     system("pause");
88     return 0;
89 }

三.总结(注意事项)

  高精度快速幂的取模操作,这里就不写了,这个应该也不难实现。

posted @ 2020-05-02 22:48  小贼的自由  阅读(1371)  评论(0编辑  收藏  举报