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