此题用最朴素的思路实现即可,需模拟加法器,乘法器,最烦人的地方是特殊情形,如末位是小数点(12.^2=144,取小数点),整数末位是0(100^2=10000),0次幂,测试用例可能超出题目中说的范围,可能包含0次幂(100.0^0=0, 0.10^1=0.1)。代码
#include <iostream>
#include <string>
using namespace std;
struct RLT {
int unit; // 本位值
int carryBit; // 进位值
};
RLT add(char ch1, char ch2, int carryBit);
RLT multiply(char ch1, char ch2, int carryBit);
string add(string op1, string op2, int x);
string multiply(string op1, char op2);
string multiply(string op1, string op2);
string remove(string str);
int main() {
string number;
int n;
while (cin >> number >> n) {
// 记录小数点位置
int punc = -1;
int len = number.length();
string multiplier = ""; // 乘数, 注意每次初始化置空
for (int i = 0; i < len; i++) {
if (number[i] == '.') {
punc = len - i - 1;
continue;
}
// 抽取出数字位
multiplier += number[i];
}
string tmpRlt = multiplier;
if(0==n) tmpRlt = "0";
else {
for(int j = 1; j < n; j++) { // 相乘次数
tmpRlt = multiply(tmpRlt, multiplier);
}
// 计算小数点位置
punc = punc*n;
int tLen = tmpRlt.length();
if(tLen!=punc && punc > 0) // 为整数时不必加小数点
tmpRlt = tmpRlt.insert(tmpRlt.length()-punc, ".");
// 注意处理末位为0的整数乘积情况
tmpRlt = remove(tmpRlt);
}
cout << tmpRlt << endl;
}
return 1;
}
// 去除字符串前后无效零位
string remove(string str) {
int start = -1;
int end = -1;
bool tag = false;
bool tag2 = false;
int index = -1;
int len = str.length();
for (int i=0; i<len; i++) {
if (str[i]!='0' && !tag) {
start = i;
tag = true;
}
if (str[len-i-1]!='0' && !tag2) {
end = len-i-1;
tag2 = true;
}
if (str[i]=='.') index = i; // 查找小数点位置
}
if (index<0) { // 无小数点情况
} else { // 处理带小数点情况
// 处理最后一位是小数点情况, 且前面位不是0
if ('.' == str[end] && '.'!=str[start])
str = str.substr(start, end-start);
else if ('.'!=str[end]) // 处理最后一位不是小数点情况, 且前面位不是0
str = str.substr(start, end-start+1);
else
str = "0";
}
return str;
}
// 一位加法器, 返回进位值, carryBit, 上一位进位值
RLT add(char ch1, char ch2, int carryBit) {
int sum = (ch1-48)+(ch2-48)+carryBit;
int unit = sum%10;
int carryBit2 = sum/10;
RLT rlt;
rlt.unit=unit;
rlt.carryBit=carryBit2;
return rlt;
}
// 一位乘法器, 返回进位值
RLT multiply(char ch1, char ch2, int carryBit) {
int product = (ch1-48)*(ch2-48)+carryBit;
int unit = product%10;
int carryBit2 = product/10;
RLT rlt;
rlt.unit=unit;
rlt.carryBit=carryBit2;
return rlt;
}
// 两个数错位相加
string add(string op1, string op2, int x) {
string rlt = "";
for (int i = 0; i < x; i++)
op2 += '0';
int len1 = op1.length();
int len2 = op2.length();
// 两个数长度对齐
if (len1<len2) {
for (int i=0; i< len2-len1; i++)
op1 = '0' + op1;
} else {
for (int i=0;i<len1-len2; i++)
op2 = '0' + op2;
}
int carryBit = 0;
int len = len1>len2?len1:len2;
RLT tmp;
for (int i=0; i<len; i++) {
tmp = add(op1[len-i-1], op2[len-i-1], carryBit);
carryBit = tmp.carryBit;
rlt = char(tmp.unit+48)+rlt;
}
// 考虑最高位进位
if (0!=tmp.carryBit) rlt = char(tmp.carryBit+48)+rlt;
return rlt;
}
// 多位数乘一位数
string multiply(string op1, char op2) {
string rlt= "";
int unit = 0;
int carryBit = 0; // 进位
int len = op1.length();
for (int k=len-1; k>=0; k--) {
RLT tRlt = multiply(op1[k], op2, carryBit);
unit = tRlt.unit; // 每一位乘积个位数字
rlt = (char(unit+48)) + rlt;
carryBit = tRlt.carryBit; // 每一位乘积十位数字
}
if(0!=carryBit)
rlt = char(carryBit+48) + rlt;
return rlt;
}
// 多位数相乘
string multiply(string op1, string op2) {
string rlt = "0";
int len2 = op2.length();
for (int i=len2-1; i>-1; i--) {
// 多位数与一位数相乘
string tmp = multiply(op1, op2[i]);
rlt = add(rlt, tmp, len2-i-1);
}
return rlt;
}