C++大作业之链表实现的高精度加法,减法,和数组实现的高精度乘法。

#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#define MAXN 100010
using namespace std ;
short d[2][MAXN] , ans[MAXN] , T[MAXN];
struct node
{
	int mun;
	node * next ;
} ;
int mun[2] ,len , ok , b[2] , N , mm ;
bool GetMun( node * & hand , node * & pre )
{
	// 是把输入的存到链表或者数组
	// b[]是存数的符号 1 代表这个数是负的
	// mun[] 是存数的位数
	pre = new node ;
	string a ;
	int n  , i , j , h = 1 ;
	cin >> a ;
	if( a == "N") return 1 ;
	n = a.size() ;
	mun[len] = n ;
	// 如果第一个数负号说明是负的
	if( a[0] == '-' )
		i = 1 , b[len] = 1 , mun[len]--;

	else i = 0 , b[len] = 0 ;
	// 这里是为乘法所有
	for( j = n - 1 ; j >= i ; j-- )
		d[len][h++] = a[j] - '0' ;
	// 这里是加减法用的
	for( ; i < n ;i++)
		if( a[i] >= '0'&& a[i] <= '9')
	{
		pre->mun = a[i] - '0' ;
		pre->next = hand ;
		hand = pre ; 
		if( i != n-1 )
			pre = new node ;
	}
		else mun[len]-- ;
	pre = hand ;
	len++ ;
	return 0 ;
}
void GetSum1( node *& pre1 , node *& pre2 , node *&hand3 , node *&pre3 )
{  
	// 算任意精度的两个数相加
	int c = 0 ;
	node *s ;
	if( mun[0] < mun[1]) {
	  // 如果两个位数不同则有一个数先算完
		// 这里我们保证都是第二个先算完
		s = pre1 ;
		pre1 = pre2 ;
		pre2 = s ;
	}
	if( mun[0] != mun[1] )
	{   // 如果两个位数不同则有一个数先算完
		while( pre2 )
		{
			pre3 = new node ;
			pre3->mun = pre1->mun + pre2->mun + c ;
			c = pre3->mun / 10 ;
			pre3->mun = pre3->mun % 10 ;
			pre2 = pre2->next ;
			pre1 = pre1->next ;
			pre3 ->next = hand3 ;
			hand3 = pre3 ;
			mm++ ;
		}
		while( pre1 )
		{
			pre3 = new node ;
			pre3->mun = c + pre1->mun ;
			c = pre3->mun/10;
				pre3->mun = pre3->mun % 10 ;
			pre1 = pre1->next ;
			pre3->next = hand3 ;
			hand3 =pre3 ;
			mm++ ;
		}
		if( c ) 
		{
			mm++ ;
			pre3 = new node ;
			pre3->mun = 1 ;
			pre3 ->next = hand3 ;
			hand3 = pre3 ;
		}
		pre3 = hand3 ;
		return ;
	}
	else 
	{
		// 如果位数相同
		while( pre2 )
		{
			pre3 = new node ;
			pre3->mun = pre1->mun + pre2->mun + c ;
			c = pre3->mun / 10 ;
			if( pre2->next != NULL )
				pre3->mun = pre3->mun % 10 ;
			pre2 = pre2->next ;
			pre1 = pre1->next ;
			pre3 ->next = hand3 ;
			hand3 = pre3 ;
			mm++ ;
		}
		if( c ) 
		{
			mm++ ;
			pre3 = new node ;
			pre3->mun = 1 ;
			pre3 ->next = hand3 ;
			hand3 = pre3 ;
		}
		pre3 = hand3 ;
		return ;
	}
}
void GetSum2( node *& pre1 ,node *& pre2 ,node *& hand3 ,node *& pre3 )
{
	int c = 0 ;
	ok = 0 ;
	node *s , *s1 = pre1 , *s2 = pre2 ;
	if( mun[0] != mun[1] )
	{
		// 如果位数不同 则两个数大小已经知道
		if( mun[0] < mun[1]) {
			s = pre1 ;
			pre1 = pre2 ;
			pre2 = s ;
			ok = 1 ;
		}
		while( pre2 )
		{
			pre3 = new node ;
			pre3->mun = pre1->mun - pre2->mun - c ;
			if( pre3->mun < 0 ) pre3->mun = pre3->mun + 10 , c = 1 ;
			else c = 0 ;
			pre2 = pre2->next ;
			pre1 = pre1->next ;
			pre3 ->next = hand3 ;
			hand3 = pre3 ;
			mm++ ;
		}
		while( pre1 )
		{
			pre3 = new node ;
			pre3->mun =  pre1->mun - c ;
			if( pre3->mun < 0 ) pre3->mun = pre3->mun + 10 , c = 1 ;
			else c = 0 ;
			pre1 = pre1->next ;
			pre3->next = hand3 ;
			hand3 =pre3 ;
			mm++ ;
		}
		pre3 = hand3 ;
		return ;
	}
	else 
	{
		// 如果位数相同 我们先用第一个减第二个
		while( pre2 )
		{
			pre3 = new node ;
			pre3->mun = pre1->mun - pre2->mun - c ;
			mm++ ;
			if( pre2->next != NULL )
			{
				if( pre3->mun < 0 ) pre3->mun = pre3->mun + 10 , c = 1 ;
				else c = 0;
			}
			else 
			{
				if( pre3->mun < 0 ) ok = 1;
				// 如果发现最后一位减出来是负的
				// 说明第一个数比较小
				// 所以需要用第二个数减去第一个数
			}
			pre2 = pre2->next ;
			pre1 = pre1->next ;
			pre3 ->next = hand3 ;
			hand3 = pre3 ;
		}
		if( ok == 1 )
		{
			// 第二个数减去第一个数
			pre1 = s2 ;
			pre2 = s1 ;
			hand3 = NULL ;
			c = 0 ;
			while( pre2 )
			{
				pre3 = new node ;
				pre3->mun = pre1->mun - pre2->mun - c ;
				mm++ ;
				if( pre2->next != NULL )
				{
					if( pre3->mun < 0 ) pre3->mun = pre3->mun + 10 , c = 1 ;
					else c = 0;
				}
				pre2 = pre2->next ;
				pre1 = pre1->next ;
				pre3 ->next = hand3 ;
				hand3 = pre3 ;
			}
		}
		pre3 = hand3 ;
		return ;
	}
}
void ab( int n )
{   // 算加法
	int i ,  c = 0 , nn = max( n , N );
	for( i = 1 ; i <= nn ; i++)
	{
		ans[i] += (T[i] + c );
		c = ans[i] / 10 ;
		ans[i] %= 10 ;
	}
	if(c) N = nn + 1, ans[nn+1] = c ;
	else N = nn ;
	return ;
}
void GetSum3()
{  
	// 这里是算高清度乘法 
	// 也是模拟小学生算数
	int i , j , c , n1 , Len ;
	memset( ans , 0 ,sizeof(ans) ) ;
	for( i = 1 ; i <= mun[1] ; i++)
	{
		c = 0 ; n1 = mun[0] ;
		for( int v = 1 ;v < i ; v++ )
			T[v] = 0 ;
		Len = i ;
		for( j = 1 ; j <= mun[0] ; j++)
		{
			T[Len++] = d[1][i] * d[0][j] + c ;
			c = T[j] / 10 ;
			T[j] %= 10 ;
		}
		// 乘完一个数就要用高精度加法把结果加到一个答案数组里面
		if(c) T[Len] = c , ab(Len);
		else ab( Len - 1 ) ;
	}

}
void ShowAns( node *& pre , char a )
{
	cout << "= " ;
	bool k = 0 ;
	if( a == '*')
	{
		mm = N ;
		int j = 0 , ok , k = 0 ;
		if( mm % 3 ) ok = 1 ;
		else ok = 0 ;
		if( b[0] == 0 && b[1] == 1 || b[0] == 1 && b[1] == 0 ) cout << "-" ;
		  
			for( int i = N ; i >= 1 ; i--)
				if( ans[i] > 0 || k )
			{
				j++ ; k = 1 ;		
				cout << ans[i] ;
				if( j == mm % 3 && ok && mm > 3 ){  cout << "," ;ok = 0 ; j = 0 ; }
				if( ! ok && j == 3 && i != 1) { cout << "," ; j = 0 ; }

			}
		if( k == 0 ) cout << "0" ;
		cout << endl ;
	}
	else {
		node *ans = pre ;
		while(pre)
		{
			if( pre->mun != 0 || k ){
				k = 1 ;
				break ;
			}
			pre = pre->next ;
		}
		if( k == 0 ) cout << "0" << endl ;
		else {
			pre = ans ;
			k = 0 ;
		    int j = 0 , kk ;
		    if( mm % 3 ) kk = 1 ;
		    else kk = 0 ;
			if(ok)cout << "-";
			while(pre)
			{
				if( pre->mun != 0 || k ){
					k = 1 ;
					j++ ;
                 cout << pre->mun ;
				if( j == mm % 3 && kk && mm >= 3 ){  cout << "," ;kk = 0 ; j = 0 ; }
				if( ! kk && j == 3 && pre->next != NULL ) { cout << "," ; j = 0 ; }
				}
				pre = pre->next ;
			}
			cout << endl ;
		}
	}
	return ;
}
void Get_what( node * &pre1 ,node *& pre2 , node * & hand3 , node * & pre3 ,char  a ) 
{
	// 这里是判断是那种类型的运算 
	if( a == '+')
	{
		if( b[0] == 0 && b[1] == 0 )
			GetSum1( pre1 , pre2 , hand3 , pre3 ) ;

		else if( b[0] == 1 && b[1] == 1 )
		{
			ok = 1 ;
			GetSum1( pre1 , pre2 , hand3 , pre3 ) ;
		}
		else if( b[0] == 0 && b[1] == 1 )
			GetSum2( pre1 , pre2 , hand3 , pre3 ) ;

		else  { 
			int j = mun[0] ;
			mun[0] = mun[1] ;
			mun[1] = j ;
			GetSum2( pre2 , pre1 , hand3 , pre3 ) ;
		}
	}
	else if( a == '-' )
	{
		if( b[0] == 0 && b[1] == 0 )
			GetSum2( pre1 , pre2 , hand3 , pre3 ) ;
		else if( b[0] == 0 && b[1] == 1 )
			GetSum1( pre1 , pre2 , hand3 , pre3 ) ;
		else if( b[0] == 1 && b[1] == 0 )
		{
			ok = 1 ;
			GetSum1( pre1 , pre2 , hand3 , pre3 ) ;
		}
		else 
		{

			GetSum2( pre2 , pre1 , hand3 , pre3 ) ;
		}
	}
	else if( a == '*') GetSum3() ;
}
void Show()
{
	cout << "************使用说明***********"  << endl ;
	cout << "   1. 可以实现任意整数的大数相加或相减"  << endl ;
	cout << "   2. 也可以实现500位以内的大数相乘" << endl ;
	cout << "   3. 输入格式是 a +(*,-) b " << endl ;
	cout << "   4. 注意加号或减号或乘号两边有空格" << endl ;
	cout << "   5. 输入N时结束输入" << endl ;
}
int main()
{         
	node *pre1 , *hand1 = NULL;
	node *pre2 , *hand2 = NULL;
	node *pre3 , *hand3 = NULL;
	char a ;
	bool ok ;
	Show() ;
	while(1){
		len = 0 ;
		N = 0 ;
		mm = 0 ;
		hand1 = NULL ;
		hand2 = NULL ;
		cout << "输入N时结束输入" << endl ;
		hand3 = NULL ;	
		ok = GetMun( hand1 ,pre1 ) ;
		if(ok)break ;
		cin >> a ;
		GetMun( hand2 ,pre2 ) ;
		Get_what( pre1 , pre2 , hand3 , pre3 , a ) ;
		ShowAns( pre3 , a ) ;
	}
	return 0 ;
}

  

posted @ 2013-05-17 23:04  _log__  阅读(964)  评论(0编辑  收藏  举报