北大OJ_1001题:求正数的高精度幂

程序说明

程序效率不高,时间复杂度为O(n^2),有待进一步的优化,呵呵

程序代码

#include <iostream>
#include <string>
#include <vector>

using namespace std;

//求两个大数的乘积(两数均为正数)
string GetProductOfTwoBigNum( string strNumLeft, string strNumRight )
{
	////////////////////////////////////
	//使用小学所学方法,计算两个大数乘积
	///////////////////////////////////

	if ( strNumRight.empty() && strNumRight.empty() )
	{
		return string("0");
	}

	//转换为数字
	for( string::size_type i = 0; i < strNumLeft.size(); ++i )
	{
		strNumLeft[i] -= '0';
	}
	for( string::size_type i = 0; i < strNumRight.size(); ++i )
	{
		strNumRight[i] -= '0';
	}

	string::size_type nMaxBits = strNumLeft.size() + strNumRight.size() + 1;//最大位数,多增加一位,便于编码
	string strProduct( nMaxBits, NULL );//保存每步乘积累加之和
	char szTemp = NULL;//每位乘积,辅助变量
	char szCarrayTemp = NULL;//进位信息

	for( int i = strNumRight.size() - 1; i >= 0; --i )
	{
		string strProductStep( nMaxBits, NULL );//保存每步之和
		int k = strNumRight.size() - i - 1;
		for( int j = strNumLeft.size() - 1; j >= 0; --j )
		{
			szTemp = ( strNumRight[i] * strNumLeft[j] + strProductStep[k] ) % 10;
			szCarrayTemp = ( strNumRight[i] * strNumLeft[j] + strProductStep[k] ) / 10;

			strProductStep[k] = szTemp;
			strProductStep[++k] += szCarrayTemp;
		}

		//将这一步结果累加strProduct中
		for( string::size_type m = 0; m < nMaxBits - 1; ++m )
		{
			szTemp = ( strProductStep[m] + strProduct[m] ) % 10;
			szCarrayTemp = ( strProductStep[m] + strProduct[m] ) / 10;

			strProduct[m] = szTemp;
			strProduct[m+1] += szCarrayTemp;
		}
	}

	//返回遍历strProduct,从而取出计算的结果
	string strResult;
	int k = nMaxBits - 1;
	while( k >= 0 && strProduct[k] == NULL )
	{
		--k;
	}
	for( ; k >= 0; --k )
	{
		strResult.push_back( strProduct[k] + '0');//转换为字符
	}

	if ( strResult.empty() )
	{
		strResult.push_back( '0' );
	}

	return strResult;
}

string GetExponentiationOfBigNum( string strBigNum, unsigned int nPower )
{
	if ( strBigNum.empty() )
	{
		return string("0");
	}

	if ( nPower == 0 )
	{
		return string("1");
	}

	//////////////////////////////////
	//计算小数位有效位数
	int nSignificantCount = 0;
	//查找小数点
	string::size_type nDotPos = strBigNum.find( '.' );
	if ( nDotPos != string::npos )
	{
		//有小数点,计算小数有效位
		string::size_type nCurPos = strBigNum.size() -1;
		while( nCurPos > nDotPos )
		{
			if ( strBigNum[nCurPos] != '0' )
			{
				break;
			}
			--nCurPos;
		}
		nSignificantCount = nCurPos - nDotPos;

 		//去除小数点后的非有效数字,即0
		strBigNum = strBigNum.substr( 0, nCurPos+1 );
	}
	nSignificantCount *= nPower;

	//去除小数点前的非有效数字,即0
	nDotPos = strBigNum.find( '.' );
	if ( nDotPos != string::npos )
	{
		string::size_type nCurPos = 0;
		while( nCurPos < nDotPos )
		{
			if ( strBigNum[nCurPos] != '0' )
			{
				break;
			}
			++nCurPos;
		}
		strBigNum = strBigNum.erase( 0, nCurPos);
	}

	//去除小数点
	nDotPos = strBigNum.find( '.' );
	if ( nDotPos != string::npos )
	{
		strBigNum.erase( nDotPos, 1 );
	}

	//迭代计算大数的幂
	string strResult("1");
	while ( nPower > 0 )
	{
		strResult = GetProductOfTwoBigNum( strResult, strBigNum );
		--nPower;
	}

	//插入小数点
	if( strResult.size() < nSignificantCount )
	{
		//在前面补0
		strResult.insert( 0, nSignificantCount - strResult.size(), '0' );
	}
	if ( nSignificantCount > 0 )
	{
		strResult.insert( strResult.size()-nSignificantCount, 1, '.' );
	}

	return strResult;
}

int main()
{
// 	string strNum;
// 	unsigned int nPower;
// 	cout << "输入正数及幂:";
// 	while( cin >> strNum >> nPower )
// 	{
// 		string strResult = GetExponentiationOfBigNum( strNum, nPower );
// 		cout << strNum << "^" << nPower << " = " << strResult << endl;
// 		cout << "--------------------------------------------------" << endl;
// 		cout << "输入正数及幂:";
// 	}

	string strNum;
	unsigned int nPower;
	while ( cin >> strNum >> nPower )
	{
		cout << GetExponentiationOfBigNum( strNum, nPower ) << endl;
	}

	return 0;
}

运行如下:

作者:山丘儿

转载请标明出处,谢谢。原文地址:http://blog.csdn.net/s634772208/article/details/46508757

时间: 2024-10-12 03:17:03

北大OJ_1001题:求正数的高精度幂的相关文章

求高精度幂(java)

求高精度幂 时间限制:3000 ms  |  内存限制:65535 KB 难度:2 描述 对数值很大.精度很高的数进行高精度计算是一类十分常见的问题.比如,对国债进行计算就是属于这类问题. 现在要你解决的问题是:对一个实数R( 0.0 < R < 99.999 ),要求写程序精确计算 R 的 n 次方(Rn),其中n 是整数并且 0 < =n <= 25. 输入 输入有多行,每行有两个数R和n,空格分开.R的数字位数不超过10位. 输出 对于每组输入,要求输出一行,该行包含精确的

NYOJ 155 求高精度幂

求高精度幂 时间限制:3000 ms  |  内存限制:65535 KB 难度:2 描述 对数值很大.精度很高的数进行高精度计算是一类十分常见的问题.比如,对国债进行计算就是属于这类问题. 现在要你解决的问题是:对一个实数R( 0.0 < R < 99.999 ),要求写程序精确计算 R 的 n 次方(Rn),其中n 是整数并且 0 < =n <= 25. 输入 输入有多行,每行有两个数R和n,空格分开.R的数字位数不超过10位. 输出 对于每组输入,要求输出一行,该行包含精确的

北京大学Online Judge 之 “求高精度幂(ID1001)”解题报告

北京大学Online Judge 之 "求高精度幂(ID1001)"解题报告 巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 题目描述: Description 对数值很大.精度很高的数进行高精度计算是一类十分常见的问题.比如,对国债进行计算就是属于这类问题. 现在要你解决的问题是:对一个实数R( 0.0 < R <99.999 ),要求写程序精确计算 R 的 n 次方(Rn),其中n 是整数并且 0 < n <

求高精度幂

求高精度幂 时间限制:3000 ms  |           内存限制:65535 KB 难度:2 描述 对数值很大.精度很高的数进行高精度计算是一类十分常见的问题.比如,对国债进行计算就是属于这类问题. 现在要你解决的问题是:对一个实数R( 0.0< R < 99.999 ),要求写程序精确计算 R的 n次方(Rn),其中n是整数并且 0 < =n< = 25. 输入 输入有多行,每行有两个数R和n,空格分开.R的数字位数不超过10位. 输出 对于每组输入,要求输出一行,该行包

nyoj 155 求高精度幂 【大数】

做了一下午,总算做出来了!! 思路:将R转换成整数,同时计算好小数的个数,计算整数的次幂之后,然后根据规律将小数点适当的时候输出(如有3位实际小数,则应在第36位输出小数点) 链接http://acm.nyist.net/JudgeOnline/problem.php?pid=155 代码: #include<stdio.h> #include<string.h> int main() { int i, j, n, doc, ans[200]; //doc是逗号后面实际的位数 ch

Poj.Grids 2951 浮点数求高精度幂

2951:浮点数求高精度幂 总时间限制: 1000ms 内存限制: 65536kB 描述 有一个实数 R ( 0.0 < R < 99.999 ) ,要求写程序精确计算 R 的 n 次方.n 是整数并且 0 < n <= 25. 输入 T输入包括多组 R 和 n. R 的值占第 1 到 第 6 列,  n 的值占第 8 和第 9 列. 输出 对于每组输入,要求输出一行,该行包含精确的 R 的 n 次方.输出需要去掉前导的 0 后后面不不要的 0 .如果输出是整数,不要输出小数点.

北大POJ题库使用指南

原文地址:北大POJ题库使用指南 北大ACM题分类主流算法: 1.搜索 //回溯 2.DP(动态规划)//记忆化搜索 3.贪心 4.图论 //最短路径.最小生成树.网络流 5.数论 //组合数学(排列组合).递推关系.质因数法 6.计算几何 //凸壳.同等安置矩形的并的面积与周长.凸包计算问题 8.模拟 9.数据结构 //并查集.堆.树形结构 10.博弈论 11.CD有正气法题目分类: 1. 排序 1423, 1694, 1723, 1727, 1763, 1788, 1828, 1838, 1

北大ACM题库习题分类与简介(转载)

在百度文库上找到的,不知是哪位大牛整理的,真的很不错! zz题 目分类 Posted by fishhead at 2007-01-13 12:44:58.0 -------------------------------------------------------------------------------- acm.pku.edu.cn 1. 排序 1423, 1694, 1723, 1727, 1763, 1788, 1828, 1838, 1840, 2201, 2376, 23

POJ 1845 Sumdiv【同余模运算+递归求等比数列和+快速幂运算】

快速幂运算在第一次训练时候就已经遇到过,这里不赘述 同余模运算也很简单,这里也不说了,无非是(a+b)%m (a*b)%m 把m弄到里面变成(a%m+b%m)%m   (a%m*b%m)%m 今天学的最重要的还是递归二分求等比数列 题目大意是给出A和B,求A^B的约数和 解这个题,首先,对A进行素因子分解得到 (PI(pi^ai))^B 然后我们有约数和公式: 对A=PI(p1^k1) A的所有因子之和为S = (1+p1+p1^2+p1^3+...p1^k1) * (1+p2+p2^2+p2^