此題用最樸素的思路實作即可,需模拟加法器,乘法器,最煩人的地方是特殊情形,如末位是小數點(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;
}