zoukankan      html  css  js  c++  java
  • 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 ;
    }
    

      

  • 相关阅读:
    销售人员个人提升经典书籍推荐
    销售必看的书籍推荐
    我在公司敲代码,你却在家和老王………————程序员的那些梗
    某程序员动了公司的祖传代码"屎山",半年后怒交辞职报告!
    为什么说程序员的前三年不要太看重工资水平?
    好的员工关系应该是怎样的?
    粒子群优化算法(PSO)python 3实现
    Python基础篇-安装python
    Python设置matplotlib.plot的坐标轴刻度间隔以及刻度范围
    空TreeList添加节点不显示
  • 原文地址:https://www.cnblogs.com/20120125llcai/p/3084711.html
Copyright © 2011-2022 走看看