您的位置:首页 > 其它

单链表实现大数加法、大数减法、大数乘法、大数指数运算

2015-11-15 00:51 651 查看
Algorithm description

1、The component of the algorithm is little, simple simulation accounts for the most.

2、Addition and subtraction are base operations,

Multiplication bases on the addition and exponentiation bases on the Multiplication.

3、All the operation begins from the lowest order so in the linked list the digit with an order n points to the digit with the order n+1, for example one:

num:1234

linked list:



4、When outputting a list, the digit with a higher order should come first than that with a lower order, but in the list , access to a digit with an order n is impossible unless the digit with the order n-1 is known. To overcome this problem, there must be a function to reverse the list, continue for the example one:linked list after reversing:



5、For the exponentiation operation, there is an algorithm:

exp(a,n)= a*exp(a,n-1), when n is even(exp(a*a,n/2), when n is odd.)

Analysis and discussion

There are many bugs in fact.

When the number is negative, function will delete the sign ‘-‘, which is inevitable to change the origin number, making it to be positive. So, a number should only be used once. For example, exp(-1,3)=mul(-1,exp(-1,2)), exp(-1,2) will be called prior to mul(), -1 become 1 after exp(-1,2), so mul(-1,exp(-1,2)) become mul(1,exp(-1,2)), that is the problem.

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cassert>
#include<ctime>
#define MAXN 10000000
using namespace std;
int arr1[MAXN+5];
int arr2[MAXN+5];
struct Node{
int value;
Node  *adj;
Node(int v,Node *n){
value=v;
adj=n;
}
};
Node *Add(Node *,Node *);
Node *Sub(Node *,Node *);
Node *Reverse(Node *L){
Node *head,*tail,*p;
p=new Node(L->value,NULL);
L=L->adj;
head=tail=p;
p->adj=head;
while(L){
p=new Node(L->value,NULL);
L=L->adj;
p->adj=head;
head=p;
}
tail->adj=NULL;
return head;
}
int Compare(Node *minuend, Node *subtractor){/*a>b return 1,a==b return 0,a<b return -1*/
int NumPowerMinuend=0,NumPowerSubtractor=0;
Node *tmpMinuend=minuend,*tmpSubtractor=subtractor;
while(tmpMinuend||tmpSubtractor){
if(NULL!=tmpMinuend){
NumPowerMinuend++;
tmpMinuend=tmpMinuend->adj;
}
if(NULL!=tmpSubtractor){
NumPowerSubtractor++;
tmpSubtractor=tmpSubtractor->adj;
}
}
if(NumPowerMinuend>NumPowerSubtractor){
return 1;
}
else if(NumPowerMinuend<NumPowerSubtractor){
return -1;
}
else{
tmpMinuend=Reverse(minuend),tmpSubtractor=Reverse(subtractor);
while(tmpMinuend&&tmpSubtractor){
if(tmpMinuend->value>tmpSubtractor->value){
return 1;
}
else if(tmpMinuend->value<tmpSubtractor->value){
return -1;
}
else{
return 0;
}
tmpMinuend=tmpMinuend->adj;
tmpSubtractor=tmpSubtractor->adj;
}
}
}
Node *CreatList(string str){
int len=str.length();
Node *p=new Node(str[len-1]-'0',NULL);/*Create the head node firstly*/
Node *tail=p;
if(len==1) return tail;
p=new  Node(str[len-2]-'0',NULL);
Node *head=p;
tail->adj=head;
for(int i=len-3;i>=0;i--){
Node  *p=new Node(str[i]-'0',NULL);
head->adj=p;
head=p;
}
/*while(tail){
cout<<tail->value;
tail=tail->adj;
}*/
return tail;
}
bool IsNegative(Node *L){
while(L->adj){
L=L->adj;
}
if(L->value==-3){
return true;
}
return false;
}
Node *Add(Node *L1,Node *L2){
int sign=1;
/*Begin:Judge whether one of L1->value and L2->value is negative or not*/
bool tmp1=IsNegative(L1),tmp2=IsNegative(L2);
if(false==tmp2&&true==tmp1){/*-a+b==b-a*/
Node *tmpHead=L1;
while(tmpHead->adj->adj){
tmpHead=tmpHead->adj;
}
delete(tmpHead->adj->adj);/*Delete the sign '-'*/
tmpHead->adj=NULL;
return Sub(L2,L1);
}
else if(false==tmp1&&true==tmp2){/*a+(-b)==a-b*/
Node *tmpHead=L2;
while(tmpHead->adj->adj){
tmpHead=tmpHead->adj;
}
delete(tmpHead->adj->adj);/*Delete the sign '-'*/
tmpHead->adj=NULL;
return Sub(L1,L2);
}
else if(tmp1&&tmp2){/*(-a)+(-b)==-(a+b)*/
sign=-1;
Node *tmpHead=L2;
while(tmpHead->adj->adj){
tmpHead=tmpHead->adj;
}
delete(tmpHead->adj->adj);
tmpHead->adj=NULL;
tmpHead=L1;
while(tmpHead->adj->adj){
tmpHead=tmpHead->adj;
}
delete(tmpHead->adj->adj);
tmpHead->adj=NULL;
}
/*End:Judge whether one of L1->value and L2->value is negative or not*/

/*a+b,a and b are positive*/
Node *tail,*p;
int carry=0;
p=new Node((*L1).value+(*L2).value,NULL);
L1=L1->adj;L2=L2->adj;
while((*p).value>=10){
carry++;
(*p).value-=10;
}
tail=p;
Node *head=tail;
tail->adj=head;
while(L1&&L2){
p=new Node((*L1).value+(*L2).value+carry,NULL);
L1=L1->adj;L2=L2->adj;
carry=0;
while((*p).value>=10){
carry++;
(*p).value-=10;
}
head->adj=p;
head=p;
}
while(L1){/*The length of L1 is longer than that of L2*/
// cout<<"L1"<<(*L1).value<<"+"<<carry<<endl;
p=new Node((*L1).value+carry,NULL);
carry=0;
while((*p).value>=10){
carry++;
(*p).value-=10;
}
head->adj=p;
head=p;
L1=L1->adj;
}
while(L2){/*The length of L2 is longer than that of L1*/
//cout<<"L2"<<(*L2).value<<"+"<<carry<<endl;
p=new Node((*L2).value+carry,NULL);
carry=0;
while((*p).value>=10){
carry++;
(*p).value-=10;
}
head->adj=p;
head=p;
L2=L2->adj;
}
if(carry!=0){
int tmpCarry,power=10;
while(carry>=10){/*If the carry is larger than 9*/
tmpCarry=carry;
while(tmpCarry>=10){
tmpCarry-=10;
}
p=new Node(tmpCarry,NULL);
head->adj=p;
head=p;
carry=(carry-tmpCarry)/power;
power*=10;
}
p=new Node(carry,NULL);
head->adj=p;
head=p;
}
if(-1==sign){/*Both L1->value and L2->value are negative*/
p=new Node(-3,NULL);
head->adj=p;
head=p;
}
if(head==tail){
tail->adj=NULL;
}
return tail;
}

Node *Sub(Node *minuend, Node *subtractor){
int sign=1;
/*BEGIN:Judge whether  L1->value and L2->value is negative or not*/
bool tmp1=IsNegative(minuend),tmp2=IsNegative(subtractor);
if(false==tmp2&&true==tmp1){/*-a-(+b)==-(a+b)*/
Node *tmpHead=minuend;
while(tmpHead->adj->adj){
tmpHead=tmpHead->adj;
}
tmpHead->adj=NULL;/*Delete the sign '-'*/
Node *tail=Add(subtractor,minuend);
tmpHead=tail;
while(tmpHead->adj){
tmpHead=tmpHead->adj;
}
Node *p=new Node(-3,NULL);/*Add the sign '-'*/
tmpHead->adj=p;
return tail;
}
else if(tmp2&&tmp1){/*-a-(-b)==b-a*/
Node *tmpHead=minuend;
while(tmpHead->adj->adj){
tmpHead=tmpHead->adj;
}
tmpHead->adj=NULL;/*Delete the sign '-'*/

tmpHead=subtractor;
while(tmpHead->adj->adj){
tmpHead=tmpHead->adj;
}
tmpHead->adj=NULL;/*Delete the sign '-'*/

Node *tmp=minuend;
minuend=subtractor;
subtractor=tmp;
}
else if(false==tmp1&&true==tmp2){/*a-(-b)==a+b*/
Node *tmpHead=subtractor;
while(tmpHead->adj->adj){
tmpHead=tmpHead->adj;
}
tmpHead->adj=NULL;/*Delete the sign '-'*/

return Add(minuend,subtractor);
}
/*END:Judge whether  L1->value and L2->value is negative or not*/

/*a-b, a and b are positive*/
int flag=Compare(minuend,subtractor);
if(-1==flag){/*Make sure that minuend->value is greater than subtractor */
sign=-1;
Node *tmp=minuend;
minuend=subtractor;
subtractor=tmp;
}
else if(0==flag){
return 0;
}

int carry=0;
Node *head,*tail,*p;
p=new Node(minuend->value-subtractor->value,NULL);
minuend=minuend->adj;subtractor=subtractor->adj;
while(p->value<0){
carry+=1;
p->value+=10;
}
head=tail=p;
head->adj=p;
while(subtractor){
p=new Node(minuend->value-subtractor->value-carry,NULL);
carry=0;
minuend=minuend->adj;subtractor=subtractor->adj;
while(p->value<0){
carry+=1;
p->value+=10;
}
head->adj=p;
head=p;
}
if(-1==sign){
p=new Node(-3,NULL);
head->adj=p;
head=p;
}
if(head==tail){
tail->adj=NULL;
}
return tail;
}

void Print(Node *L){
Node *head,*tail,*p;
head=Reverse(L);

Node *OutputNode=head;
if(-3==OutputNode->value){
// cout<<-1<<endl;
cout<<"-";
}
else{
// cout<<-2<<endl;
cout<<OutputNode->value;
}
OutputNode=OutputNode->adj;
while(OutputNode){
cout<<OutputNode->value;
OutputNode=OutputNode->adj;
}
}
Node *ToPower(Node *L,int NumPower){
Node *p;
for(int i=1;i<=NumPower;i++){
p=new Node(0,NULL);
p->adj=L;
L=p;
}
return L;
}
Node *Mul(Node *L1,Node *L2){
int sign=1;
/*BEGIN:Judge the sign of answer and delete the sign '-' where it exists*/
bool tmp1=IsNegative(L1),tmp2=IsNegative(L2);
if(false==tmp1&&true==tmp2){/* a*(-b) */
sign=-1;
Node *tmpHead=L2;
while(tmpHead->adj->adj){
tmpHead=tmpHead->adj;
}
tmpHead->adj=NULL;/*Delete the sign '-'*/
}
else if(true==tmp1&&false==tmp2){/* (-a)*b */
sign=-1;
Node *tmpHead=L1;
while(tmpHead->adj->adj){
tmpHead=tmpHead->adj;
}
tmpHead->adj=NULL;/*Delete the sign '-'*/
}
else if(true==tmp1&&true==tmp2){
Node* tmpHead1=L2;
while(tmpHead1->adj->adj){
tmpHead1=tmpHead1->adj;
}
tmpHead1->adj=NULL;/*Delete the sign '-'*/

Node *tmpHead=L1;
while(tmpHead->adj&&tmpHead->adj->adj){
tmpHead=tmpHead->adj;
}
tmpHead->adj=NULL;/*Delete the sign '-'*/
}
/*END;Judge the sign of answer and delete the sign '-' where it exists*/

/* a*b, a and b are positive*/
Node  *tmpAnstail,*AnsTail,*p;
int NumPower=0;
while(L2){
// cout<<"L2->VALUE"<<L2->value<<endl;
tmpAnstail=L1;
for(int i=1;i<L2->value;i++){/*a*b=b+b+...+b(plus for a-1 times)*/
tmpAnstail=Add(tmpAnstail,L1);
}

if(0==NumPower){/* Create the head node of the answer*/
AnsTail=tmpAnstail;
}
else{/* Create new node of the answer*/
AnsTail=Add(AnsTail,ToPower(tmpAnstail,NumPower));
}
NumPower++;
L2=L2->adj;
}
if(-1==sign){
Node *tmpHead=AnsTail;
while(tmpHead->adj){
tmpHead=tmpHead->adj;
}
tmpHead->adj=new Node(-3,NULL);
}
return AnsTail;
}
Node *Exp(Node *L,int NumExponent){
if(0==NumExponent){
return new Node(1,NULL);
}
else if(1==NumExponent){
return L;
}
if(NumExponent&1){
return Mul(L,Exp(L,NumExponent-1));
}
return Exp(Mul(L,L),NumExponent/2);
}
int main(void)
{
freopen("output.txt","w",stdout);
Node *L1=CreatList("823456780");
Node *L2=CreatList("222222222");
Node *L3=CreatList("-1111");
Node *L4=CreatList("-3333");
Node *L5=CreatList("2222");
Node *L6=CreatList("4444");
Node *L7=CreatList("2");
Node *L8=CreatList("-1");
Node *L9=CreatList("5555");
Node *L10=CreatList("-666");
Node *L11=CreatList("111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
Node *L12=CreatList("222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222");
Node *L13=CreatList("-333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333");
/*FOR GEVERAL INTEGER */
/*
Print(Add(L1,L2));
Print(Add(L4,L3));//-a+(-b)
Print(Add(L4,L6));//-a+b
Print(Add(L5,L3));//a+(-b)
Print(Add(L5,L6));//a+b
*/
/*
Print(Sub(L6,L5)); //a-b(a>b)
Print(Sub(L5,L6)); //a-b(a<b)
Print(Sub(L3,L5)); //-a-b
Print(Sub(L3,L4)); //-a-(-b)
*/

/*
Print(Mul(L7,L9));//a*b
Print(Mul(L3,L7)); //a*(-b)
Print(Mul(L10,L4)); //(-a)*(-b)
Print(Mul(L4,L9)); //(-a)*b
*/

/*
Print(Exp(L6,10));
Print(Exp(L4,3));//Error!
*/

/*FOR BIG INTEGER*/
/*
Print(Exp(L12,10));
Print(Add(L13,L12));
Print(Mul(L12,L13));
Print(Sub(L13,L12));
*/
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息