#include<iostream>
#include<string>
#include<math.h>
using namespace std;
struct LinkNode
{
int data; //記錄每個節點的整數(小於10000)
LinkNode *next; //記錄下一個節點的地址
LinkNode *prev; //記錄前一個節點的地址
};
class LinkList
{
private:
LinkNode *head0,*head1; //head0,head1分別記錄兩個整數鏈表的頭指針
LinkNode *currptr;
LinkNode *result; //result記錄結果鏈表的頭指針
public:
LinkList(); //構造函數,初始化鏈表
~LinkList(); //析構函數,釋放空間
void Creat(string a); //引入字符串,創立兩個鏈表,分別表示兩個整數
void Add(); //實現兩個整數相加
void Display(); //顯示結果
void addtwo(); //節點多的作為被加數,少的作為加數,實現整數絕對值大的加小的
};
int sum(int n);
LinkList::LinkList() //構造函數,初始化鏈表
{
head0=new LinkNode; //申請一個空間記錄整數的符號和節點數
head1=new LinkNode;
head0->next=head0;
head0->prev=head0; //初始化鏈表,建立雙向循環鏈表
head1->next=head1;
head1->prev=head1;
result=new LinkNode;
result->next=result;
result->prev=result;
currptr=NULL;
}
LinkList::~LinkList() //析構函數,釋放空間
{
LinkNode *p1=head0,*p2=head1,*p3=result; //三個指針分別指向三條鏈表的頭指針
while(p1!=p1->prev)
{
p1->prev->next=p1->next;
p1->next->prev=p1->prev;
currptr=p1;
p1=p1->next;
delete currptr;
}
while(p2!=p2->prev) //逐個刪除節點,釋放空間
{
p2->prev->next=p2->next;
p2->next->prev=p2->prev;
currptr=p2;
p2=p2->next;
delete currptr;
}
while(p3!=p3->prev)
{
p3->prev->next=p3->next;
p3->next->prev=p3->prev;
currptr=p3;
p3=p3->next;
delete currptr;
}
// 刪除 p1,p2,p3;
}
void LinkList::Creat(string a) //引入字符串,創立兩個鏈表,分別表示兩個整數
{
int i=0,j=0,m=0,n=0,k=0,l=0,s=0,w=0; //i記錄字符串,j記錄加數節點數;s記錄被加數節點數,w標記字符串中的'-'號,
//k記錄字符串中的字符轉化為整數的值,l使每個節點記錄4位
while(a[m]!=';') m++; //m記錄字符串中被加數的字符數
n=m;
while(a[n]!='\0') n++; //n記錄字符串的總字符數
if(a[0]=='-')
{
head0->data=(-1); //記錄整數符號
w=1;
}
else {head0->data=1;}
for(i=m-1;i>=w;i--)
{
if(a[i]!=',') //把字符轉化為整數
{
k+=(a[i]-'0')*sum(l);
l++;
}
if(a[i]==','||i==w)
{
currptr=new LinkNode; //把整數存到雙向循環鏈表中
currptr->data=k;
currptr->next=head0;
currptr->prev=head0->prev;
head0->prev->next=currptr;
head0->prev=currptr;
head0=currptr;
s++; //節點數加1
k=0; //重新初始化k和l
l=0;
}
}
head0->prev->data*=s; //存儲整數符號和節點數
//與建第一個整數鏈表一樣,建立第二個整數鏈表head1
k=0;l=0;
if(a[m+1]=='-')
{
head1->data=(-1);
m++;
}
else
head1->data=1;
for(i=n-1;i>m;i--)
{
if(a[i]!=',')
{
k+=(a[i]-'0')*sum(l);
l++;
}
if(a[i]==','||i==m+1)
{
currptr=new LinkNode;
currptr->data=k;
currptr->next=head1;
currptr->prev=head1->prev;
head1->prev->next=currptr;
head1->prev=currptr;
head1=currptr;
j++;
k=0;
l=0;
}
}
head1->prev->data*=j;
}
void LinkList::Add() //實現兩個整數相加
{
LinkNode *temp;
if(abs(head0->prev->data)>abs(head1->prev->data)) //兩個整數中,絕對值大的為被加數
addtwo();
else if(abs(head0->prev->data)<abs(head1->prev->data))
{
temp=head0;
head0=head1;
head1=temp;
addtwo();
}
else if(abs(head0->prev->data)==abs(head1->prev->data))
{
int k1,k2;
LinkNode *p=head0,*q=head1; //如果節點數相同,則判斷節點中數值大小
while(p->data==q->data&&p!=head0->prev->prev&&q!=head1->prev->prev)
{
p=p->next;
q=q->next;
}
k1=p->data;
k2=q->data;
if(k1>k2)
addtwo();
else
{
temp=head0;
head0=head1;
head1=temp;
addtwo();
}
}
}
void LinkList::addtwo() //節點多的作為被加數,少的作為加數,實現整數絕對值大的加小的
//默認head0存的整數絕對值比head1大
{
int s=0,m1=head0->data,m2=head1->data;
m1=(head0->prev->data/abs(head0->prev->data)); //head0的符號
m2=(head1->prev->data/abs(head1->prev->data)); //head1的符號
LinkNode *p=head0->prev->prev,*q=head1->prev->prev;
result->data=head0->prev->data; //存結果的節點數和符號
while(q!=head1->prev) //head0存的整數絕對值比head1大,即head0的節點數大於或等於head1
{
currptr=new LinkNode;
currptr->data=(p->data)*m1+(q->data)*m2+s; //兩整數相加
if((m1*m2)>0) //如果符號相同
{
if(abs(currptr->data)-10000>=0) //相加後超過10000,則進位
{
s=currptr->data/10000;
currptr->data=abs(currptr->data)%10000;
}
else //abs(currptr->data)-10000<0,不進位
{
s=0;
currptr->data=abs(currptr->data);
}
}
else if(m1>0&&m2<0) //符號不同,在此相當於實現兩個正整數相減
{
s=0;
if(currptr->data<0) //小於0,向前一位借1
{
currptr->data+=10000;
s=-1;
}
}
else if(m1<0&&m2>0)
//符號不同,在此相當於實現負整數加上正整數
{
s=0;
if(currptr->data>0) //大於0,
{
currptr->data=10000-currptr->data;
s=1;
}
else currptr->data=abs(currptr->data);
}
currptr->next=result; //存入鏈表
currptr->prev=result->prev;
result->prev->next=currptr;
result->prev=currptr;
result=currptr;
p=p->prev;
q=q->prev;
}
//當head0節點數比head1長時,繼續建立鏈表
while(p!=head0->prev)
{
currptr=new LinkNode;
currptr->data=p->data*m1+s;
s=currptr->data/10000;
if((m1*m2)>0)
{
if(abs(currptr->data)-10000>=0)
{
s=currptr->data/10000;
currptr->data=abs(currptr->data)%10000;
}
else {s=0;currptr->data=abs(currptr->data);}
}
else if(m1>0&&m2<0)
{
s=0;
if(currptr->data<0)
{
currptr->data+=10000;
s=-1;
}
}
else if(m1<0&&m2>0)
{
s=0;
if(currptr->data>0)
{
currptr->data=10000-currptr->data;
s=1;
}
else currptr->data=abs(currptr->data);
}
currptr->data=abs(currptr->data)%10000;
currptr->next=result;
currptr->prev=result->prev;
result->prev->next=currptr;
result->prev=currptr;
result=currptr;
p=p->prev;
}
if(s!=0) //處理相加後,進位問題
{
currptr=new LinkNode;
currptr->data=abs(s);
currptr->next=result;
currptr->prev=result->prev;
result->prev->next=currptr;
result->prev=currptr;
result=currptr;
result->prev->data=m1*(abs(result->prev->data)+1);
}
}
void LinkList::Display() //顯示結果
{
LinkNode *p=result;
int FuHao=result->prev->data/abs(result->prev->data);//結果的符號
while(p->data==0&&p!=result->prev->prev) //當運算後前幾個節點的數據為0時,不輸出
{
p=p->next;
result->prev->data=(abs(result->prev->data)-1)*FuHao; //結果記錄非0節點數
}
cout<<FuHao*p->data; //首先顯示符號和第一個節點中的數
if(abs(result->prev->data)!=1) p=p->next; //判斷非0節點數是否為1
while(p!=result->prev->prev) //繼續輸出
{
cout<<","; //每4位一組,並用','隔開
cout.width(4);
cout.fill('0');
cout<<p->data;
p=p->next;
}
if(p==result->prev->prev&&abs(result->prev->data)!=1) //顯示最後一個節點數據
{
cout<<",";
cout.width(4);
cout.fill('0');
cout<<p->data;
}
cout<<endl;
}
int sum(int n) //計算10的乘方
{
int i,s=1;
for(i=1;i<=n;i++)
{
s=s*10;
}
return s;
}
int main() //主函數
{
cout<<"* 任意長整數的加法 *\n\n";
cout<<"* 注意:輸入時每四位用逗號隔開 *\n\n";
cout<<"* 如:123456789 *\n\n";
cout<<"* 輸入格式為:1,2345,6789 *\n\n";
cout<<"* 兩個數之間用';'隔開 *\n\n";
cout<<"\n";
string ch;
cout<<"請輸入整數1;整數2:\n";
cin>>ch; //輸入任意長字符串
LinkList List; //定義鏈表對象
List.Creat(ch); //把字符串轉化為整數,並存到鏈表中
List.Add(); //實現兩個整數相加
cout<<"兩整數的和為:";
List.Display(); //輸出結果
}
這個代碼裡輸入兩個數的時候要用“;”隔開,這個地方怎麼改成讓它分別輸入兩個數然後相加,我改成下面這種但前面格式好像不對,不知道怎麼改
string ch1,ch2;
cout<<"請輸入整數1:\n";
cin>>ch1;
cout<<"請輸入整數2:\n";
cin>>ch2;
LinkList List;
List.Creat(ch1,ch2);
List.Add();
cout<<"兩整數的和為:";
List.Display();
}
string ch1,ch2,ch3;
cout<<"請輸入整數1:\n";
cin>>ch1;
cout<<"請輸入整數2:\n";
cin>>ch2;
ch1=ch1+";"+ch2;
LinkList List;
List.Creat(ch1);
List.Add();
cout<<"兩整數的和為:";
List.Display();