您的位置:首页 > 编程语言 > C语言/C++

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

2013-05-17 23:04 736 查看
#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 ;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: