求高精度幂数

求高精度幂数

个人信息:就读于燕大本科软件工程专业 目前大三;

本人博客:google搜索“cqs_2012”即可;

个人爱好:酷爱数据结构和算法,希望将来从事算法工作为人民作出自己的贡献;

编程语言:C++ ;

编程坏境:Windows 7 专业版 x64;

编程工具:vs2008;

制图工具:office 2010 powerpoint;

硬件信息:7G-3 笔记本;

真言

去往火焰山,炼就红色眼

题目

百炼 1001 幂运算

网址 http://bailian.openjudge.cn/practice/1001/

解法

用字符串处理。

对这个系统不是很了解,多次尝试后才发现这个系统不兼容很多东西,如下

system(“pause”);

<Windows.h>

对于输入输出控制,不能按照给的例子指定输入输出的个数,而用while(cin>>)来控制是否继续输入。

哎,一把辛酸泪。

看题:此问题是幂操作,求高精度运算,问题不难,在于细心,考虑整形溢出即可,利用字符串模拟整形运算

算法

个人算法用C++代码表示如下(代码有部分用过以前写过的程序,所以看起来比较乱,但是纯个人写的代码,没有copy)

#include<iostream>
#include <string>
using namespace std;

// 小数的幂次方
string FloatPower(string a,unsigned int b);
bool XiaoshuCheck(string a);

bool Check_all_number(string a);
// 小数乘法
string FloatMult(string a,string b);
std::pair<string,int> StandardXiaoshu(string a);
string MULT_Int(string a,string b);
bool Standardization(string &a);
string IntToChar(int i);
int CharToNumber(char c);
string ADD_Int(string a,string b);
string AddInt(string a,string b);
string SubInt(string a,string b);
char Compare(string a,string b);
char CompareXiaoshu(string a,string b);

// 小数的幂次方
string FloatPower(string a,unsigned int b)
{
	if(!a.empty() && XiaoshuCheck(a))
	{
		string result = "1";
		for(unsigned int i = b-1;i<b;i--)
		{
			result = FloatMult(a,result);
		}
		if(result[0] == '0'&&result[1] == '.')
			result = result.substr(1,result.length()-1);
		return result;

	}
	else if(!a.empty() &&! XiaoshuCheck(a))
	{
		string result = "1";
		for(unsigned int i = b-1;i<b;i--)
		{
			result = MULT_Int(a,result);
		}
		return result;
	}
}

bool XiaoshuCheck(string a)
{
	bool xiaoshu = false ;
	string b = a ;

	// 找出小数点
	for(unsigned int i=0;i<b.length();i++)
		if(b[i] == '.')
		{
			xiaoshu = true;

			// 去掉小数点后判断是否符合整数形式
			b = b.substr(0,i)+b.substr(i+1,b.length()-i-1);
			if(Check_all_number(b) != true)
				xiaoshu = false;
			break;
		}
		return xiaoshu ;
}

// 小数乘法
string FloatMult(string a,string b)
{
	// 把小数扩展成整数,然后去操作
	// (a*b)/(小数点长度之和)
	//
	std::pair<string,int> sa = StandardXiaoshu(a);
	std::pair<string,int> sb = StandardXiaoshu(b);
	a = sa.first;
	b = sb.first;

	// a*b,得到放大结果
	string r = MULT_Int(a,b);

	// 结果是负数怎么办?把其变成正数
	bool fushu = false;
	if(r[0] == '-')
	{
		fushu = true;
		r = r.substr(1,r.length()-1);
	}

	// 结果产生很多 0,并且小数长度大于0
	unsigned int maxlength = sa.second + sb.second;
	while(r[r.length()-1] == '0' && maxlength > 0)
	{
		r = r.substr(0,r.length()-1) ;
		maxlength -- ;
	}

	// 如果结果是小数,并且小于1,前面补0
	while(r.length() <= maxlength)
	{
		r = "0" +r;
	}

	if(maxlength == 0 || Compare(r.substr(r.length()-maxlength,maxlength),"0") == '=')
		r = r.substr(0,r.length()-maxlength);
	else
		// 加上小数点
		r = r.substr(0,r.length()-maxlength)+"."+r.substr(r.length()-maxlength,maxlength);
	// 如果结果是负数,怎么办
	if(fushu == true)
		r = '-'+r;
	// 返回结果
	return r;

}

bool Check_all_number(string a)
{
	if(a.empty())
		return false ;
	string::size_type L = a.size(),i = 0;
	if(a[0] == '-')
		i++;
	while( i < L )
	{
		if( a[i] < '0' || a[i] > '9')
			return false;
		i++;
	}
	return true ;
}

std::pair<string,int> StandardXiaoshu(string a)
{
	// 数据域
	bool fushu = false ;
	string b;
	unsigned int i;

	// 检查a是否是小数
	if(a[0] == '-')
	{
		fushu = true;
		a = a.substr(1,a.length()-1);
	}
	// a是小数
	if(XiaoshuCheck(a) == true)
	{
		// 把小数部分的末尾0去掉
		while(true)
		{
			if(a[a.length()-1] == '0')
				a = a.substr(0,a.length()-1);
			else break;
		}
		// 把整数部分的前面的0去掉
		for(i=0;i<a.length();i++)
			if(a[i] == '.')
			{
				b = a.substr(0,i);
				a = a.substr(i+1,a.length()-i-1);
				break;
			}
			Standardization(b);
			a = b+a;
			i = a.length() - b.length();
			if(fushu == true)
				a = "-"+a;

			// 返回值
			return std::make_pair(a,i);

	}
	// a是整数
	else if(Check_all_number(a) == true)
	{
		Standardization(a);
		if(fushu == true)
			a = "-"+a;
		return std::make_pair(a,0);
	}
}

string MULT_Int(string a,string b)
{
	// exception of input
	if( a.empty() )
		return b;
	else if( b.empty() )
		return "0";
	if(!Check_all_number(a) || !Check_all_number(b))
	{
		return "exception of input Multiplies_Int";
	}
	Standardization(a);
	Standardization(b);
	string::size_type i = a.size(),j = b.size();
	string c = "0",d = "";
	bool fushu = (a[0] == '-' && b[0] != '-')||(a[0] != '-' && b[0] == '-');
	if(a[0] == '-')
		a = a.substr(1,a.size());
	if(b[0] == '-')
		b = b.substr(1,b.size());

	int jinwei = 0;
	for( j = b.size()-1 ; j < b.size() ;j--)
	{
		// each number of b to * a
		jinwei = 0;
		for( i = a.size()-1 ; i < a.size() ;i-- )
		{
			d = IntToChar(   ( CharToNumber(a[i]) * CharToNumber(b[j]) + jinwei ) % 10 )+ d ;
			jinwei = ( CharToNumber(a[i]) * CharToNumber(b[j]) + jinwei ) / 10 ;
		}
		if(jinwei)
			d = IntToChar(jinwei) +d;
		// add all number result
		c = ADD_Int(c,d);
		d = "";
		unsigned int zero = 0 ;
		while( zero < b.size() - j )
		{
			d = d + '0';
			zero ++;
		}

	}

	Standardization(c);
	if( fushu && c != "0" )
		return '-'+c;
	else return c;
}

bool Standardization(string &a)
{
	if(!Check_all_number(a))
	{
		cout<<a<<" exception of input Standardization"<<endl;
		return false;
	}
	string::size_type i = 0 ;
	bool fushu = false ;
	if( a[0] == '-' )
	{
		fushu = true ;
		i = 1 ;
	}
	while(i < a.size())
	{
		if(a[i] != '0')
			break;
		i++;
	}
	if(i == a.size())
		i--;
	a = a.substr(i,a.size()-i) ;
	if( fushu && a != "0")
		a = '-' + a ;
	return true ;
}

string IntToChar(int i)
{
	if( i >= 0 && i <= 9 )
	{
		string c = "";
		return c+char(i+48);
	}
	else
	{
		cout<<i<<" exception of input IntToChar"<<endl;
		return "e";
	}
}

// make char to the int number
int CharToNumber(char c)
{
	if( c >= '0' && c <= '9' )
		return int(c - '0');
	else
	{
		cout<<c<<" exception of input CharToNumber "<<endl;
		return 0;
	}
};

string ADD_Int(string a,string b)
{
	// exception of input
	if( a.empty() )
		return b;
	else if( b.empty() )
		return "0";
	if(!Check_all_number(a) || !Check_all_number(b))
	{
		return "exception of input ADD_Int";
	}
	Standardization(a);
	Standardization(b);	

	if(a[0] != '-' && b[0] != '-')
		return AddInt(a,b);
	else if(a[0] != '-'&& b[0] == '-')
		return SubInt( a,b.substr( 1,b.size() ) );
	else if(a[0] == '-'&& b[0] != '-')
		return SubInt(b,a.substr(1,a.size()));
	else return '-'+AddInt(a.substr(1,a.size()),b.substr( 1,b.size() ));
};

string SubInt(string a,string b)
{
	// exception of input
	if(!Check_all_number(a) || !Check_all_number(b))
		return "exception of input MinusInt";
	Standardization(a);
	Standardization(b);
	// particular string of input
	if(a.empty())
	{
		if(b.empty())
			return "0";
		else
			return "-"+b;
	}
	else if(b.empty())
	{
		return a;
	}

	// normal number a < b
	string c = "";
	bool check = true ;
	if(Compare(a,b) == '=')
		return "0";
	else if(Compare(a,b) == '<')
	{
		c = a ;
		a = b ;
		b = c ;
		c = "";
		check = false ;
	}
	// normal number a >= b
	string::size_type i = a.size()-1, j = b.size()-1;
	int jiewei = 0,now;

	while(i < a.size() && j < b.size())
	{
		now = CharToNumber(a[i]) - CharToNumber(b[j]) - jiewei ;

		if( now < 0 )
		{
			jiewei = 1;
			now = 10 + now ;
		}
		else jiewei = 0;
		c = IntToChar(now)  + c ;
		i--;j--;
	}
	while(i < a.size())
	{
		now = CharToNumber(a[i]) - jiewei ;
		if( now < 0 )
		{
			jiewei = 1;
			now = 10 + now ;
		}
		else jiewei = 0;
		c = IntToChar( now )  + c ;
		i--;
	}
	Standardization(c);
	if(!check)
		c = '-' + c;
	return c;
};

string AddInt(string a,string b)
{
	// exception of input
	if( a.empty() )
		return b;
	else if( b.empty() )
		return "0";
	if(!Check_all_number(a) || !Check_all_number(b))
	{
		return "exception of input AddInt";
	}
	Standardization(a);
	Standardization(b);
	string::size_type i = a.size()-1 ,j = b.size()-1 , k = 0 ;
	string c = "";
	int jinwei = 0;
	while( i < a.size() && j < b.size() )
	{
		c = IntToChar( ( CharToNumber(a[i]) + CharToNumber(b[j]) + jinwei ) % 10 ) + c;
		jinwei = ( CharToNumber(a[i]) + CharToNumber(b[j]) + jinwei ) / 10;
		j--;i--;
	}
	while( j < b.size()  )
	{
		c =  IntToChar( ( CharToNumber(b[j]) + jinwei ) % 10 ) + c;
		jinwei = ( jinwei + CharToNumber(b[j]) ) / 10;
		j--;
	}
	while( i < a.size() )
	{
		c =  IntToChar( ( CharToNumber(a[i]) + jinwei ) % 10 ) + c;
		jinwei = ( jinwei + CharToNumber(a[i]) ) / 10;
		i--;
	}
	if( jinwei )
		c = IntToChar(  jinwei  ) + c;
	Standardization(c);
	return c;
};

char Compare(string a,string b)
{
	if(a.empty() || b.empty())
	{
		cout<<"error of input compare";
		return 'e';
	}
	else
	{
		if(!Check_all_number(a) || !Check_all_number(b))
		{
			return 'e';
		}
		Standardization(a);
		Standardization(b);
		if(a[0] == '-' && b[0] != '-')
			return '<';
		else if( a[0] != '-' && b[0] == '-')
			return '>';
		bool fushu = (a[0] == '-');

		if(a.size() > b.size() )
			return fushu?'<':'>';
		else if(a.size() == b.size())
		{
			for(string::size_type i = 0;i < a.size(); i++)
			{
				if(a[i] > b[i])
					return fushu?'<':'>';
				if(a[i] < b[i])
					return fushu?'>':'<';
			}
			return '=';
		}
		return fushu?'>':'<';
	}
}

char CompareXiaoshu(string a,string b)
{
	if(XiaoshuCheck(a) && XiaoshuCheck(b))
	{
		pair<string,int> sa= StandardXiaoshu(a);
		pair<string,int> sb= StandardXiaoshu(b);
		int length = sa.second - sb.second;
		while(length != 0)
		{
			if(length < 0)
			{
				sa.first +="0";
				length++;
			}
			else if(length > 0)
			{
				sb.first +="0";
				length--;
			}
			return Compare(sa.first,sb.first);
		}
	}
}

int main()
{

	string a;
	int b;
	while(cin>>a>>b)
		cout<<FloatPower(a,b)<<endl;
	//system("pause");
	return 0;
}

求高精度幂数,布布扣,bubuko.com

时间: 2024-08-27 21:26:58

求高精度幂数的相关文章

求高精度幂(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-1001 求高精度幂

[题目描述] 给定R与n,求Rn的精确值,其中(0.0<R<99.99, n为整数0<n<=25). [思路分析] 1. 存储结构 由于R最大不超过100,n不会超过25,故Rn不会超过50位,保险起见采用100位的int数组.数组采用与字符串的逆序方式存储,即str=”123456”中str[0]=’1’而存入int数组后,int[0]=’6’.因此,在输入时候,可以通过字符串的字符个数以及是否存在小数点来判断这个数字的位数,根据位数从最高位(str[0])开始存储数字.这样虽然

使用java求高精度除法,要求保留N位小数

题目要求是高精度除法,要求保留N位小数(四舍五入),并且当整数部分为0时去除0的显示 1 import java.math.BigDecimal; 2 import java.util.Scanner; 3 4 public class BD 5 { 6 public static void main(String[] args) 7 { 8 Scanner scanner = new Scanner(System.in); 9 while(scanner.hasNext()) 10 { 11

POJ 1001 Exponentiation 求高精度幂

Exponentiation Time Limit: 500MS   Memory Limit: 10000K Total Submissions: 147507   Accepted: 36006 Description Problems involving the computation of exact values of very large magnitude and precision are common. For example, the computation of the n