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 ; }