博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++大作业之链表实现的高精度加法,减法,和数组实现的高精度乘法。
阅读量:4680 次
发布时间:2019-06-09

本文共 7009 字,大约阅读时间需要 23 分钟。

#include
#include
#include
#include
#define MAXN 100010using 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 ;}

  

转载于:https://www.cnblogs.com/20120125llcai/archive/2013/05/17/3084711.html

你可能感兴趣的文章
密码策略限制最大与最小长度
查看>>
正则表达式模式
查看>>
使用iframe实现同域跨站提交数据
查看>>
Mouse点击之后,复制GridView控件的数据行
查看>>
ASP.NET开发,从二层至三层,至面向对象 (2)
查看>>
如何查看自己电脑支持OpenGL core版本
查看>>
页面元素定位 XPath 简介
查看>>
[转]loadrunner:系统的平均并发用户数和并发数峰值如何估算
查看>>
Linux下Tomcat重新启动
查看>>
HTML Table to Json
查看>>
Theano 学习笔记(一)
查看>>
1.7 节点进行排序显示
查看>>
web最佳实践
查看>>
spring 集成shiro 之 自定义过滤器
查看>>
验证密码不允许有连续三位重复的正则表达式
查看>>
python 中对list去重
查看>>
Mono Libgdiplus库
查看>>
js模糊查询案例
查看>>
c语言基础知识要点
查看>>
Android模拟器无法上网访问网络失败解决办法
查看>>