X.er86

导航

POJ_1001:Exponentiation

原题链接:http://poj.org/problem?id=1001

分类:高精度计算

算法:按照小学生手算的方法进行计算,利用字符串对数字进行处理。

c++源代码:

  1 #include<iostream>
  2 #include<string>
  3 #include<vector>
  4 
  5 using namespace std;
  6 
  7 string times_func(string s1, string s2);    // 用于计算两个大数的乘法(高精度乘法)
  8 string solve(string s, int n);                // 用于计算整数阶乘
  9 
 10 int main()
 11 {
 12     string s;
 13     int n;
 14     while(cin >> s >> n)
 15     {
 16         int index = s.find_first_of(".");    // 定位小数点在字符串中的位置
 17         int m = s.length() - index - 1;        
 18         // 首先将带小数点的数变为整数类型,这里用了C++ String 的迭代器
 19         for (string::iterator it = s.begin(); it != s.end(); ++it)
 20         {
 21             if (*it == '.') 
 22             {
 23                 s.erase(it);
 24                 break;
 25             }
 26         }
 27         string result = solve(s,n);            // 此处获得的是一个整数的阶乘解
 28         int k = 0;
 29         string::iterator it;                // k为控制小数点位置的标识
 30         for (it = result.end(); k <= m*n; k++, --it) {}
 31         result.insert(++it,'.');            // 在相应位置插入小数点,如果小数点后为m位,其n次方通常为m*n位小数
 32         // 处理小数点都为0的情况
 33         index = 0;                            
 34         for (int i = 0; result[i] != '.'; i++)
 35         {
 36             if (result[i] != '0') break;
 37             else index++;
 38         }
 39         result = result.substr(index,result.length());
 40         // 处理小数点末尾连续为0的情况
 41         index = 0;
 42         for (int i = result.length()-1; result[i] != '.'; i--)
 43         {
 44             if (result[i] != '0') break;
 45             else index++;
 46         }
 47         result = result.substr(0,result.length()-index);
 48         int l = result.length();
 49         // 处理整数情况
 50         if (result[l-1] == '.') result = result.substr(0,l-1);
 51         cout << result << endl;
 52     }
 53     return 0;
 54 }
 55 
 56 // 高精度阶乘
 57 string solve(string s, int n)
 58 {
 59     string result = s;
 60     for (int i = 1; i < n; i++)
 61     {
 62         string tmp = "";
 63         tmp = times_func(result,s);
 64         result = "";
 65         for (int i = tmp.length()-1; i>=0; i--) result += tmp[i];
 66     }
 67     return result;
 68 }
 69 
 70 // 高精度乘法
 71 string times_func(string s1, string s2)
 72 {
 73     int n1 = s1.length();
 74     int n2 = s2.length();
 75     vector<string> nums;
 76     string result = "";
 77     for (int i = n1-1; i >= 0; i--)
 78     {
 79         int m;
 80         int carry = 0;
 81         string tmp = "";
 82         for (int j = i; j < n1-1; j++) tmp += '0';
 83         for (int j = n2-1; j >= 0; j--)
 84         {
 85             m = ((s1[i]-48) * (s2[j]-48) + carry) % 10;
 86             carry = ((s1[i]-48) * (s2[j]-48) + carry) / 10;
 87             tmp += (char)(m+48);
 88         }
 89         if (carry > 0) tmp += (char)(carry+48);
 90         nums.push_back(tmp);
 91         
 92     }
 93 
 94     // 高精度乘法中包含了高精度加法的运算
 95     if (nums.size() != 0) result = nums[0];
 96     for (int i = 1; i < nums.size(); i++)
 97     {
 98         string tmp = nums[i];
 99         int l = tmp.length();
100         int c = 0;
101         int k = 0;
102         for (int j = 0; j < result.length(); j++,k++)
103         {
104             if(result[j]+tmp[k]+c-96 >= 10) 
105             {
106                 result[j] = result[j]+tmp[k]+c-48-10;
107                 c = 1;
108             }
109             else 
110             {
111                 result[j] = result[j]+tmp[k]+c-48;
112                 c = 0;
113             }
114         }
115         for (; k<l; k++)
116         {
117             if(tmp[k]+c-48 >= 10) 
118             {
119                 result.push_back(tmp[k]+c-10);
120                 c = 1;
121             }
122             else 
123             {
124                 result.push_back(tmp[k]+c);
125                 c = 0;
126             }
127         }
128         if (c == 1) result.push_back('1');
129     }
130 
131     return result;
132 }

后续工作思考:由于高精度计算本质上是对字符串的处理,因此上述代码用到了C++中标准的STL库,如Vector,String,这给本题的求解带来很大的便利。但是后来查看了题源,为1988年的题目,很老,那时候应该只有pascal,c以及非标准的C++,标准C++中的STL库还没有出现,因此其实本题最好用C语言重新实现,在有空的时候重写一下。

posted on 2012-11-30 14:29  X.er86  阅读(165)  评论(0编辑  收藏  举报