无限长整数运算

#include<iostream>
#include<string>
using namespace std;
//************************************  定义结构  *************************************
struct node             
{int data;node*next;};
//************************************  show1  ****************************************
void show1(node*head,int i)                 //将链表反向输出
{cout<<"将以上两整数相加后结果是:/n";
node*a,*b;int t,k,j,w;
a=head;b=head->next;
if(b==NULL)goto l;              //如果结果只有一位,则链表不反向,直接goto
for(k=1;1;k++)                  //以下十多行是链表反向的代码
{t=a->data;
a->data=b->data;
b->data=t;
a=b;
b=b->next;
if(b==NULL)break;}
for(;k!=1;k--){a=head;b=head->next;
for(j=1;j<=k-1;j++)
{t=a->data;
a->data=b->data;
b->data=t;
a=b;
b=b->next;}}
l:if(i)cout<<'-';        
w=1;              
a=head;                      //以下是按整数输出的表示习惯,每三位一组,间用逗号分隔
while(a)
{a=a->next;
w++;}                        //w-1是结果的位数
switch((w-1)%3)
{case 1:cout<<head->data;if(head->next!=NULL)cout<<',';head=head->next;w=1;while(head)
   {cout<<head->data;
        if(w%3==0&&head->next!=NULL)cout<<',';
          head=head->next;w++;}break;
 case 2:cout<<head->data;head=head->next;cout<<head->data;if(head->next!=NULL)cout<<',';head=head->next;
  w=1;while(head)
   {cout<<head->data;
        if(w%3==0&&head->next!=NULL)cout<<',';
          head=head->next;w++;}break;
 default:w=1;while(head)
   {cout<<head->data;
        if(w%3==0&&head->next!=NULL)cout<<',';
          head=head->next;w++;}}cout<<endl;
cout<<"********************************************************************"<<endl;
cout<<"版本:2005.2.19"<<endl;
cout<<"Copyright(c) 2005 C2 704 C++Development Team"<<endl;
cout<<"all rights reserved.未经授权不得复制."<<endl;
cout<<"********************************************************************"<<endl;}

//************************************  加法函数c1  ************************************
void c1(node*head,node*head1,int u)    
{int i=0;node*head2=NULL,*t=new node,*e;
while(1)
{
if((head->data+head1->data+i)>=10)      //第一种情况:同一位上的两数相加大于十,
{t->data=i+head->data+head1->data-10;   //满十进一,i就是向上一位进一的"1"
 if(head2==NULL)head2=t;
    else e->next=t;
    e=t;
 t=new node;
 i=0;i++;
 head=head->next;
 head1=head1->next;
if(head==NULL&&head1==NULL)        //head与head1两整数位数一样多
{t->data=1;e->next=t;e=t;e->next=NULL;break;}
else if(head!=NULL&&head1==NULL)   //head链表的整数比head1的位数多   
{while(1+head->data==10&&head!=NULL)
{t->data=1+head->data-10;
e->next=t;e=t;
t=new node;
head=head->next;
if(head==NULL)break;}
if(head==NULL){
t->data=1;
e->next=t;
e=t;
e->next=NULL;break;}
else {t->data=1+head->data;
e->next=t;e=t;e->next=head->next;break;}
}
else if(head1!=NULL&&head==NULL)  //head1链表的整数比head的位数多
{while(1+head1->data==10&&head1!=NULL)
{t->data=1+head1->data-10;
e->next=t;e=t;
t=new node;
head1=head1->next;
if(head1==NULL)break;}
if(head1==NULL){
t->data=1;
e->next=t;
e=t;
e->next=NULL;break;}
else {t->data=1+head1->data;
e->next=t;e=t;e->next=head1->next;break;}}}
else                          //另一种情况:同一位上的两数相加小于等于十
{   t->data=i+head->data+head1->data;
    i=0;
 if(head2==NULL)head2=t;
    else e->next=t;
    e=t;
    t=new node;
    head=head->next;
 head1=head1->next;
if(head==NULL&&head1==NULL){delete t;e->next=NULL;break;}  //head与head1两整数位数一样多
else if(head!=NULL&&head1==NULL){delete t;e->next=head;break;}//head链表的整数比head1的位数多
else if(head1!=NULL&&head==NULL){delete t;e->next=head1;break;}//head1链表的整数比head的位数多
}}show1(head2,u);}      
//*********************************** 符号互异位数不同的两整数加法函数c2 *********************************
void c2(node*head,node*head1,int u)     //head存放绝对值位数较多的整数
{int i=0;node*head2=NULL,*t=new node,*e;
while(head1!=NULL)
{if(i+head->data-head1->data<0)  //正整数与负整数的加法运算转换成两个正整数的减法运算    
{t->data=i+head->data+10-head1->data;
if(head2==NULL)head2=t;
    else e->next=t;
    e=t;
 t=new node;
 i=0;i--;
 head=head->next;
 head1=head1->next;
while(head!=NULL&&head1==NULL)//因为head存放绝对值位数较多的整数,所以head1比head先指向NULL
{ if(i+head->data>0) {t->data=i+head->data;e->next=t;
                      e=t;e->next=head->next;break;}
else if(i+head->data<0){ t->data=i+head->data+10;e->next=t;e=t;
                        t=new node;i=0;i--;head=head->next;}
else if(i+head->data==0){t->data=0;
if(head->next==NULL){delete t;e->next=NULL;e=head2;
while(1&&e->next!=NULL)
{if(e->next->data==0&&e->next->next==NULL)
{   e->next=NULL;e=head2;if(e->next==NULL)break;continue;}
if(e->next->data!=0&&e->next->next==NULL)break;
e=e->next;}              
break;}
          e->next=t;e=t;e->next=head->next;break;}}
}
else {t->data=head->data-head1->data+i;
i=0;
if(head2==NULL)head2=t;
    else e->next=t;
    e=t;
    t=new node;
    head=head->next;
 head1=head1->next;
if(head!=NULL&&head1==NULL){delete t;e->next=head;break;}//head的位数长于head1
}}show1(head2,u);}
//***********************************  符号互异位数相同的两整数加法函数c3  **********************************
void c3(node*head,node*head1,int u)      //绝对值位数较多的放在head链表
{int i=0;node*head2=NULL,*t=new node,*e;
while(1)
{if(i+head->data-head1->data<0)//正整数与负整数的加法运算转换成两个正整数的减法运算
{t->data=i+head->data+10-head1->data;
 if(head2==NULL)head2=t;
    else e->next=t;
    e=t;
 t=new node;
 i=0;i--;              //i是不够减时向高位借一的那个"1"
 head=head->next;
 head1=head1->next;}
else {t->data=head->data-head1->data+i;  
     i=0;
    if(head2==NULL)head2=t;
    else e->next=t;
    e=t;
    t=new node;
    head=head->next;
 head1=head1->next;
 if(head==NULL&&head1==NULL){delete t;e->next=head;
 e=head2;
 while(1&&e->next!=NULL)
{if(e->next->data==0&&e->next->next==NULL)
{   e->next=NULL;e=head2;if(e->next==NULL)break;continue;}
if(e->next->data!=0&&e->next->next==NULL)break;
e=e->next;} 
 break;}}}
show1(head2,u);
}
//###########################*********  主函数main  ***********###############################
int main()
{string a,b,h;node*head,*head1,*s,*p,*q;   s=new node;int k,d,s1,t1,u,m=0;
cout<<"请输入一个整数(带逗号):" ;
cin>>a;                       //输入的长整数以字符串形式存于string变量a,b中
cout<<"请输入另一个整数(带逗号):";
cin>>b;
//****************  输入的是两个负整数  ***********************
if(a[0]==45&&b[0]==45)        //判断整数符号
{for(k=0;a[k]!=NULL;k++);     //此行是计算长整数位数,存于k中     
s->data=a[k-1]-48;   //以下是把字符串反向存于一条链表中,每一结点存一个字符串元素(以整数形式)
head=NULL;
while(1)
{if(head==NULL)head=s;
else p->next=s;
p=s;
if(k-2<=0)break;    //加了等号,即不把负号存入链表中
s=new node;         //也即表示不带符号进行运算
k--;
if(a[k-1]==44)k--;                  
s->data=a[k-1]-48;}
p->next=NULL;
for(k=0;b[k]!=NULL;k++);
s=new node;
s->data=b[k-1]-48;
head1=NULL;
while(1)
{if(head1==NULL)head1=s;
else q->next=s;
q=s;
if(k-2<=0)break;      //加了等号,即不把负号存入链表中
s=new node;           //也即表示不带符号进行运算
k--;
if(b[k-1]==44)k--;       //不把逗号存入链表中
s->data=b[k-1]-48;}
q->next=NULL;
t1=1;        //t1是输送给c1函数的,用来判断符号
c1(head,head1,t1); }
//*****************************  输入的是两符号互异(包括零和负数)  *****************************
else if(a[0]==45&&b[0]>=48||b[0]==45&&a[0]>=48)   //两符号互异(包括零和负数)
{  for(k=0;a[k]!=NULL;k++);                     //四个for语句来计算a与b除符号外的位数
   for(d=0;b[d]!=NULL;d++);
   for(s1=0;a[k-1]!=NULL&&a[k-1]!=45;s1++,k--);
   for(t1=0;b[d-1]!=NULL&&b[d-1]!=45;t1++,d--);
    k=s1;d=t1;
if(k>d&&a[0]==45&&b[0]>=48)                      //先输入a是负且绝对值大,后输入b是正,得出结果是负号
{g: for(k=0;a[k]!=NULL;k++);
 for(d=0;b[d]!=NULL;d++);
 s->data=a[k-1]-48;
   head=NULL;
   while(1)
   {if(head==NULL)head=s;
   else p->next=s;
   p=s;
   if(k-2<=0)break;          //加了等号,即不把负号存入链表中         
   s=new node;               //也即表示不带符号进行运算
   k--;
   if(a[k-1]==44)k--;       
   s->data=a[k-1]-48;}
   p->next=NULL;
 s=new node;
   s->data=b[d-1]-48;
   head1=NULL;
   while(1)
   {if(head1==NULL)head1=s;
   else q->next=s;  
   q=s;
   if(d-2<0)break;          //由于b字符串不带负号,所以不加等号
   s=new node; 
   d--;
   if(b[d-1]==44)d--;        
   s->data=b[d-1]-48;}
   q->next=NULL;
   u=1;                           //用u来判断结果的符号
   c2(head,head1,u);}  //因head位数多于head1,故head放在head1的左边
else if(k<d&&a[0]==45&&b[0]>48)        //先输入a是负且绝对值小,后输入b是正,得出结果是正号
{ l: for(k=0;a[k]!=NULL;k++);          
  for(d=0;b[d]!=NULL;d++);
  s->data=a[k-1]-48;
   head=NULL;
   while(1)
   {if(head==NULL)head=s;
   else p->next=s;
   p=s;
   if(k-2<=0)break;           
   s=new node;
   k--;
   if(a[k-1]==44)k--;        
   s->data=a[k-1]-48;}
   p->next=NULL;
 s=new node;
   s->data=b[d-1]-48;
   head1=NULL;
   while(1)
   {if(head1==NULL)head1=s;
   else q->next=s;
   q=s;
   if(d-2<0)break;           
   s=new node;
   d--;
   if(b[d-1]==44)d--;        
   s->data=b[d-1]-48;}
   q->next=NULL;
   u=0;                                         //因已知结果为正,故赋值给u,使函数得以识别结果符号
   c2(head1,head,u);}                           //因head1位数多于head,故head1放在head的左边
else if(k>d&&b[0]==45&&a[0]>48){h=a;a=b;b=h;goto l;}//先输入a是正且绝对值大,后输入b是负,得出结果是正号
else if(k<d&&b[0]==45&&a[0]>=48){h=a;a=b;b=h;goto g;}//先输入a是正且绝对值小,后输入b是负,得出结果是负号      
else if(k==d)                    //输入的是符号互异位数相同的两整数
{j:  for(k=0;a[k]!=NULL;k++);
     for(d=0;b[d]!=NULL;d++);
 if(k!=s1)                     //a为负数
{ for(k=1,d=0;a[k]!=NULL&&b[d]!=NULL;k++,d++)
 {   if(a[k]>b[d])             //a是负数,而且绝对值a大于b
 {for(k=0;a[k]!=NULL;k++);
 for(d=0;b[d]!=NULL;d++);
 s->data=a[k-1]-48;
   head=NULL;
   while(1)
   {if(head==NULL)head=s;
   else p->next=s;
   p=s;
   if(k-2<=0)break;          //加了等号,即不把负号存入链表中         
   s=new node;               //也即表示不带符号进行运算
   k--;
   if(a[k-1]==44)k--;        
   s->data=a[k-1]-48;}
   p->next=NULL;
 s=new node;
   s->data=b[d-1]-48;
   head1=NULL;
   while(1)
   {if(head1==NULL)head1=s;
   else q->next=s;
   q=s;
   if(d-2<0)break;           
   s=new node;
   d--;
   if(b[d-1]==44)d--;        
   s->data=b[d-1]-48;}
   q->next=NULL;
   u=1;m=0;
   c3(head,head1,u);   //head存放绝对值大的数,所以head放在head1的左边  
 break;}                       
else if(a[k]<b[d])                 //a是负数,但绝对值b大于a
 {for(k=0;a[k]!=NULL;k++);
 for(d=0;b[d]!=NULL;d++);
 s->data=a[k-1]-48;
   head=NULL;
   while(1)
   {if(head==NULL)head=s;
   else p->next=s;
   p=s;
   if(k-2<=0)break;          //加了等号,即不把负号存入链表中          
   s=new node;               //也即表示不带符号进行运算
   k--;
   if(a[k-1]==44)k--;        
   s->data=a[k-1]-48;}
   p->next=NULL;
 s=new node;
   s->data=b[d-1]-48;
   head1=NULL;
   while(1)
   {if(head1==NULL)head1=s;
   else q->next=s;
   q=s;
   if(d-2<0)break;           
   s=new node;
   d--;
   if(b[d-1]==44)d--;        
   s->data=b[d-1]-48;}
   q->next=NULL;
   u=0;m=0;
  c3(head1,head,u);        //head1存绝对值放大的数,所以head1放在head的左边
  break;}
else if(a[k]==b[d])       //相反数相加得零,转换成判断除符号外得字符是否完全相同,
{m=1;continue;}}          //若相同,则赋值给m,令cout语句执行
if(m){cout<<"将以上两整数相加后结果是:/n";
     cout<<0<<endl;}}
 else if(d!=t1)              //b为负数
 {h=a;a=b;b=h;goto j;}}}     //变成a存放放负数,利用goto语句,避免打重复的代码
//***********************************  输入的是两个正整数  ************************************
else
{for(k=0;a[k]!=NULL;k++);
s->data=a[k-1]-48;
head=NULL;
while(1)
{if(head==NULL)head=s;
else p->next=s;
p=s;
if(k-2<0)break;  //k-2<0若改为"<="则这部分与上面的"输入的是两个负整数"源程序完全相同
s=new node;
k--;
if(a[k-1]==44)k--;       
s->data=a[k-1]-48;}
p->next=NULL;
for(k=0;b[k]!=NULL;k++);
s=new node;
s->data=b[k-1]-48;
head1=NULL;
while(1)
{if(head1==NULL)head1=s;
else q->next=s;
q=s;
if(k-2<0)break;  //k-2<0若改为"<="则这部分与上面的"输入的是两个负整数"源程序完全相同
s=new node;
k--;
if(b[k-1]==44)k--;       
s->data=b[k-1]-48;}
q->next=NULL;
s1=0;
c1(head,head1,s1);}return 0;}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值