poj 1001 Exponentiation
2011-07-17 23:28
351 查看
// 题意:大数求幂 ,输入实数R,整数n,求R^n #include <iostream> #include <string> using namespace std; int compare(string str1, string str2) { while(!str1.empty()&&str1[0]=='0') { str1.erase(0,1); } while(!str2.empty()&&str2[0]=='0') { str2.erase(0,1); } if(str1.size() > str2.size()) //长度长的整数大于长度小的整数 return 1; else if(str1.size() < str2.size()) return -1; else return str1.compare(str2); //若长度相等,从头到尾按位比较,compare函数:相等返回0,大于返回1,小于返回-1 } int to_int(char ch) { return ch-48; } char to_char(int i) { return (char)(i+48); } string to_str(int n) { string str; while(n) { str.insert(str.begin(),n%10+48); n=n/10; } return str; } void dipose_head(string& str,int sign) //str为引用类型 { str.erase(0, str.find_first_not_of('0')); //去除结果中的前导0 if(str.empty()) str = "0"; if((sign == -1) && (str[0] != '0')) //处理符号位 ,若str[0] == '0'说明结果是0,就不必要在前面加上- str = '-' + str; } //高精度加法 string ADD_INT(string str1, string str2) //计算str1 + str2的值,处理成 str1 ,str2 >= 0 { if(str1.empty()) str1="0"; if(str2.empty()) str2="0"; string MINUS_INT(string str1, string str2); //要事先声明MINUS_INT string str; if(str1[0] == '-') { if(str2[0] == '-') { str = ADD_INT(str1.erase(0, 1), str2.erase(0, 1)); if(str[0] != '0') str = "-" + str; } else str = MINUS_INT(str2, str1.erase(0, 1)); } else { if(str2[0] == '-') str = MINUS_INT(str1, str2.erase(0, 1)); else //str1 ,str2 >= 0的情况 { string::size_type l1, l2; int i; l1 = str1.size(); l2 = str2.size(); if(l1 < l2) //把两个整数对齐,短整数前面加0补齐 for(i = 1; i <= l2 - l1; i++) str1 = '0' + str1; else for(i = 1; i <= l1 - l2; i++) str2 = '0' + str2; int int1 = 0, int2 = 0; //int2 记录进位 for(i = str1.size() - 1; i >= 0; i--) { int1 = ( str1[i]+str2[i] - 96 + int2 ) % 10; int2 = ( str1[i]+str2[i] - 96 + int2 ) / 10; str = to_char(int1) + str; } if(int2 != 0) str = to_char(int2) + str; //处理最后的进位 } } return str; } //高精度减法 string MINUS_INT(string str1, string str2) //计算str1 - str2的值,先处理成 str1 ,str2 >= 0,再处理成 str1 > str2 >= 0 { if(str1.empty()) str1="0"; if(str2.empty()) str2="0"; int sign = 1; //sign 为符号位 string str; if(str2[0] == '-') { if(str1[0]!='-') str = ADD_INT(str1, str2.erase(0, 1)); else str=MINUS_INT(str2.erase(0,1),str1.erase(0,1)); } else { if(str1[0]=='-') { str = ADD_INT(str1.erase(0, 1), str2); if(str[0] != '0') str = "-" + str; } else //str1 ,str2 >= 0的情况 { int res = compare(str1, str2); if(res == 0) return "0"; //二者相等 if(res < 0) { sign = -1; str1.swap(str2); } string::size_type temp_int; temp_int = str1.size() - str2.size(); int cf=0; //cf保存借位 for(int i = str2.size() - 1; i >= 0; i--) { if(str1[i + temp_int] - cf < str2[i]) { str = to_char(str1[i + temp_int] - cf - str2[i] + 10) + str; cf=1; } else { str =to_char(str1[i + temp_int] - cf - str2[i]) + str; cf=0; } } for(int i=temp_int-1;i>=0;--i) { if(str1[i]-cf>='0') //看是否够借位减 { str=char(str1[i]-cf)+str; cf=0; } else { str=char(str1[i]-cf+10)+str; cf=1; } } dipose_head(str,sign); } } return str; } //高精度乘法 string MULTIPLY_INT(string str1, string str2) { if(str1.empty()) str1="0"; if(str2.empty()) str2="0"; int sign = 1; //sign 为符号位 if(str1[0] == '-') { sign *= -1; str1 = str1.erase(0, 1); } if(str2[0] == '-') { sign *= -1; str2 = str2.erase(0, 1); } if(str1=="0"||str2=="0") return "0"; int i, j; string str; string::size_type len1, len2; len1 = str1.size(); len2 = str2.size(); for(i = len2 - 1; i >= 0; i --) //实现手工乘法 { string temp_str; int int1 = 0, int2 = 0, int3 = to_int(str2[i]); if(int3 != 0) { for(j = 1; j <= len2-1 - i; j++) temp_str = '0' + temp_str; for(j = len1 - 1; j >= 0; j--) { int1 = (int3 * to_int(str1[j]) + int2) % 10; int2 = (int3 * to_int(str1[j]) + int2) / 10; temp_str = to_char(int1) + temp_str; } if(int2 != 0) temp_str = to_char(int2) + temp_str; } str = ADD_INT(str, temp_str); } if((sign == -1) && (str[0] != '0')) str = '-' + str; return str; } //高精度除法 string DIVIDE_INT(string str1, string str2, int flag) //flag = 1时,返回商; flag = 0时,返回余数 { if(str1.empty()) str1="0"; if(str2.empty()) str2="0"; string quotient, residue; //定义商和余数,sign1,sign2判断商和余数的符号 int sign1 = 1, sign2 = 1; if(str2 == "0") //判断除数是否为0 return "ERROR!"; if(str1 == "0") //判断被除数是否为0 return "0"; if(str1[0] == '-') { str1 = str1.erase(0, 1); sign1 *= -1; sign2 = -1; //余数的符号由被除数的符号决定 } if(str2[0] == '-') { str2 = str2.erase(0, 1); sign1 *= -1; } int res = compare(str1, str2); if(res < 0) { quotient = "0"; residue = str1; } else if(res == 0) { quotient = "1"; residue = "0"; } else //str1>str2 { string::size_type len1, len2; len1 = str1.size(); len2 = str2.size(); string temp_str; temp_str.append(str1, 0, len2 - 1); //添加从str1[0]到str1[len2 - 2] for(int i = len2 - 1; i < len1; i++) //模拟手工除法 { temp_str = temp_str + str1[i]; for(char ch = '9'; ch >= '0'; ch --) //试商 { string str; str = str + ch; if(compare(MULTIPLY_INT(str2, str), temp_str) <= 0) //在compare增添的两个while()语句在这里发挥作用,倘若缺失,比如计算10/1,第二次的temp_str=00,按照compare函数的定义,00就会比1大了 { quotient = quotient + ch; temp_str = MINUS_INT(temp_str, MULTIPLY_INT(str2, str)); break; } } } residue = temp_str; //residue就不用判断前面是否带0,因为temp_str = MINUS_INT(...),MINUS_INT把0处理了 if(quotient[0]=='0') quotient.erase(0,1); //商前面最多只有一个0 } if((sign1 == -1) && (quotient!="0")) quotient = "-" + quotient; if((sign2 == -1) && (residue != "0")) residue = "-" + residue; if(flag == 1) return quotient; else return residue; } int main() { string R; int n; while(cin>>R>>n) { int pos=R.find('.',0); R.erase(pos,1); string res="1"; for(int i=0;i<n;++i) res=MULTIPLY_INT(res,R); //实数R的小数位有 R.size()-pos 位, R^n 小数位则有 (R.size()-pos)*n 位 //假若R=0.001,去除小数点实际上变成1,所以需要在运算结果前面补足0 while(res.size()<(R.size()-pos)*n) { res.insert(res.begin(),'0'); } res.insert(res.end()-(R.size()-pos)*n,'.'); //恢复小数点 while(res[res.size()-1]=='0') //舍弃小数点后的尾部0 res.erase(res.size()-1,1); if(res[res.size()-1]=='.') //说明结果是整数,则要舍弃小数点 res.erase(res.size()-1,1); cout<<res<<endl; } return 0; }
相关文章推荐
- POJ解题报告_1001_Exponentiation
- poj 1001 Exponentiation
- 【POJ】 1001-Exponentiation 【高精度乘法】
- POJ 1001 Exponentiation(java+处理字符串)
- POJ-1001-Exponentiation
- poj 1001 Exponentiation(高精度乘法)
- POJ 1001--Exponentiation
- hdu 1063 poj 1001 Exponentiation(幂)
- POJ 1001 Exponentiation [解题报告] Java
- POJ1001《Exponentiation》方法:模拟 高精度
- POJ 1001 Exponentiation 大浮点数乘法
- 【原】 POJ 1001 Exponentiation 大整数乘法 解题报告
- poj 1001 Exponentiation(高精度运算)
- poj 1001 Exponentiation
- POJ-1001-Exponentiation
- 【poj1001】 Exponentiation
- poj 1001 -- Exponentiation (大数计算,模拟)
- POJ 1001(Exponentiation)
- POJ 1001 "Exponentiation"
- 高精度乘法计算 poj1001 Exponentiation C代码