题意:高精度求幂。难度:3星。
/*
* POJ 1001 Exponentiation
* 求R^n, 其中0.0 < R < 99.999, 0 < n <= 25;
*
* 1) 高精度高位数计算;
* 2) 将字符串转换为数组,按位计算;
* 3) 采用连乘求幂 或 将次数转换为二进制数以减少相乘次数;
*
*/
#include <iostream>
using namespace std;
#define MAX_NUMBER_LENGTH 200
void multiply(int [], int, int, int []);
int main()
{
char inputChar[7], output[MAX_NUMBER_LENGTH];
int n;
int inputInt[6], result[MAX_NUMBER_LENGTH];
int length, decimalLength, resultLength;
int i, j;
while (cin >> inputChar >> n)
{
/* 将字符串转化为数组 */
length = strlen(inputChar);
memset(inputInt, 0, sizeof(int) * 6); /* 避免 上一数据造成影响 */
for (i = length - 1, j = 0, decimalLength = 0; i >= 0; i--, j++)
{
if ('.' == inputChar[i])
{/* 确定小数位数 */
decimalLength = j;
i--;
length--;
}
inputInt[j] = inputChar[i] - '0';
}
decimalLength *= n;
/* 连乘求幂 */
memset(result, 0, sizeof(int) * MAX_NUMBER_LENGTH); /* 避免 上一数据造成影响 */
memcpy(result, inputInt, sizeof(int) * 6);
resultLength = length + 1;
while (--n)
{
multiply(inputInt, length, resultLength, result);
resultLength += length;
}
/* 数组转换为字符串输出 */
int flag = 0; /* 从高位开始碰到“非零字符”的标志 */
for (i = resultLength, j = 0; i >= 0; i--)
{
/* 从高位开始转换 */
if (i == decimalLength - 1)
{/* 加上小数点 */
output[j++] = '.';
flag = 1;
}
if (!result[i] && !flag)
{/* 忽略小数点左边的无意零 */
continue;
}
else
{
flag = 1;
output[j++] = result[i] + '0';
}
}//for (i = resultLength, j = 0; i >= 0; i--)
while (--j && '.' == output[j] || '0' == output[j])
{/* 去除小数点右边的无意零 */
if ('.' == output[j])
{
j--;
break;
}
}
output[++j] = '\0'; /* 为字符串添加终止符 */
cout << output << endl;
}
return 0;
}
void multiply(int inputInt[], int length, int resultLength, int result[])
{
/* c[]记录进位, d[][]记录被乘数与乘数每一位相乘所得 */
int c[MAX_NUMBER_LENGTH] = {0};
int d[MAX_NUMBER_LENGTH][MAX_NUMBER_LENGTH] = {0};
int tmpResult[MAX_NUMBER_LENGTH];
int i, j;
memcpy(tmpResult, result, sizeof(int) * MAX_NUMBER_LENGTH);
memset(result, 0, sizeof(int) * MAX_NUMBER_LENGTH);
for (j = 0; j < resultLength; j++)
{
for (i = 0, c[0] = 0; i < length + 1; i++)
{/* 被乘数与乘数每一位相乘 */
c[i] = inputInt[i] * tmpResult[j] + c[i];
d[j][i + j] = c[i] % 10;
c[i + 1] = c[i] / 10;
}
for(i = 0, c[0] = 0; i < length + j + 1; i++)
{/* 被乘数与乘数每一位相乘所得求和 */
c[i] = result[i] + d[j][i] + c[i];
result[i] = c[i] % 10;
c[i + 1] = c[i] / 10;
}
}
}

本文介绍了解决POJ1001Exponentiation问题的方法,通过高精度计算实现小数指数幂的求解。采用字符串转数组的方式进行按位计算,并利用连乘法减少运算次数。
1586

被折叠的 条评论
为什么被折叠?



