1. 程式人生 > >C++實現string類型的大數相加(帶小數)

C++實現string類型的大數相加(帶小數)

字符 urn sin 個數 dem 做了 優化 count 變量

近日,做了一道阿裏給的大數相加的編程題。題目大意如下:

輸入兩個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;
}

  運行結果:

技術分享圖片

其中,部分代碼仍可進行優化(博主比較懶...就沒繼續了),如判斷是否帶小數的判斷以及後續的函數整合等。

C++實現string類型的大數相加(帶小數)