C++实现string类型的大数相加(带小数)

时间:2024-01-21 13:42:08

近日,做了一道阿里给的大数相加的编程题。题目大意如下:

输入两个string类型的数,如12.223  11,判断输入字符串是否合法。合法则输出true以及相加结果(true 23.223),非法则输出false """"。

期间几经修改,在判断合法方面排除了如.212以及122.这种错误(出现除数字以及.以外的错误亦已排除)。

主要的思路是将小数与整数部分进行分离,分别相加。由于小数部分可能想整数部分进位,需要进行进位判断。

完整代码如下:

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

string max_i,min_i;
bool carry_dem = false;									//判断小数是否需要向整数进位 

void count_int(string s1,string s2)						//计算整数部分的和 
{
	max_i = s1;min_i = s2;
	if(s2.size()>s1.size())
	{
		max_i = s2;										//取长度大的数为max 
		min_i = s1;
	}
	
	if(carry_dem)										//完成进位 
		max_i[max_i.size() -1] ++;
	
	for(int i = min_i.size()-1,j = max_i.size()-1; i>=0;i--,j--)		//模拟整数加的过程 
	{
		max_i[j] += min_i[i] -\'0\';										//选择将结果保存在max变量中 
		
		if(max_i[j] > \'9\') 
		{
			if(j > 0)
			{
				max_i[j - 1] ++;
				max_i[j] -= 10;
			}
			else
			{
				max_i = "1" + max_i;
				max_i[j] -= 10;
			}
		}
	}
	
}

string max_d,min_d;
void count_dem(string s1,string s2)					//对小数部分进行相加 
{
	max_d = s1;min_d = s2;
	if(s2.size()>s1.size())
	{
		max_d = s2;
		min_d = s1;
	}
	
	for(int i=min_d.size()-1;i>=0;i--)
	{
		max_d[i] += min_d[i] -\'0\';
		if(max_d[i] > \'9\') 
		{
			if(i > 0)
			{
				max_d[i - 1] ++;
				max_d[i] -= 10;
			}
			else
			{
				carry_dem = true;					//设置进位标志 
				max_d[i] -= 10;
			}
		}
	}
		
}

int main(){
	string s1,s2;
	cin>>s1>>s2;
	
	int i,j,k;
	
	bool legal = true;
	for(i = 0; i< s1.size();i++)					//完成字符串是否合法的判断 
	{
		if(((s1[i]<\'0\'||s1[i]>\'9\')&&(s1[i] != \'.\'))||(s1[s1.size()-1] == \'.\')||(s1[0] == \'.\'))
			legal = false;
	}
	for(i = 0; i< s2.size();i++)
	{
		if(((s2[i]<\'0\'||s2[i]>\'9\')&&(s2[i] != \'.\'))||(s2[s2.size()-1] == \'.\')||(s2[0] == \'.\'))
			legal = false;
	}
	
	string integer_1,integer_2;						//取出字符串的整数部分 
	string demical_1,demical_2;						//取出字符串的小数部分 

	
	if(!legal)
		cout<<"false "<<"\"\"\"\"";
	else
	{
		bool wi_dem1 = false,wi_dem2 = false;		//判断是否带小数 
		int pos_s1 = 0,pos_s2 = 0;
		
		for(i = 0; i< s1.size();i++)				
			if(s1[i] == \'.\')
			{
				wi_dem1 = true;
			}
				
		for(i = 0; i< s2.size();i++)
			if(s2[i] == \'.\')
			{
				wi_dem2 = true;
			}
		

		if((!wi_dem1)&&(!wi_dem2))					//两个数均不带小数部分 
		{
			count_int(s1,s2);
			cout<<"true "<<max_i;
		}		
		else
		{	
			if(wi_dem1)								//第一个数带小数时分离整数、小数部分
			{
				pos_s1 = s1.find(".");
				integer_1 = s1.substr(0,pos_s1);
				demical_1 = s1.substr(pos_s1+1);
			}
			
			if(wi_dem2)								//第二个数带小数时分离整数、小数部分 
			{
				pos_s2 = s2.find(".");
				integer_2 = s2.substr(0,pos_s2);
				demical_2 = s2.substr(pos_s2+1);
			}
					
			if(wi_dem2 && wi_dem1)					//均带小数 
			{
				count_dem(demical_1,demical_2);
				count_int(integer_1,integer_2);
				
				cout<<"true "<<max_i<<"."<<max_d;
			}
			else if(!wi_dem2 && wi_dem1)
			{
				count_int(integer_1,s2);
				cout<<"true "<<max_i<<"."<<demical_1;
			}	  
			else
			{
				count_int(integer_2,s1);
				cout<<"true "<<max_i<<"."<<demical_2;
			}
		}	
	}
	
	return 0;
}

  运行结果:

其中,部分代码仍可进行优化(博主比较懒...就没继续了),如判断是否带小数的判断以及后续的函数整合等。