首页 > 代码库 > 求高精度幂数

求高精度幂数

求高精度幂数

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

本人博客: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;
}