• 求高精度幂数


    求高精度幂数

    个人信息:就读于燕大本科软件project专业 眼下大三;

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







  • 相关阅读:
    动态内存Treap
    最大流Dinic
    图的遍历
    Aho_Corasick自动机(AC自动机)
    邻接表
    COJ 3007 Mr.Yang的小助手
    COJ 0601&0602 动态规划(二)及加强
    Codeforces 603A Alternative Thinking
    HDU 2222 Keywords Search
    codeforce--600D
  • 原文地址:https://www.cnblogs.com/llguanli/p/7094012.html
Copyright © 2020-2023  润新知