大数相乘(分治法实现时间复杂度为O(n^1.59))

来源:互联网 发布:国外网络电视直播apk 编辑:程序博客网 时间:2024/05/30 23:02

/* * Author: dengzhaoqun * Date:    2011/04/11 */  #include <stdio.h>#include <stdlib.h>#include <string.h> #define MAX_LENGTH 1000 //------------define the data struct--------------------typedef struct{char *cptr;int len;}CharNum;//------------the end of defining data struct---------- //------the methods' declaration------void DelHeadZero(CharNum *Result);CharNum *DoMinus(CharNum *A,CharNum *B,int *flag);int GetMax(int x,int y);int GetMin(int x,int y);CharNum *GetNum(char ch);void Init(char *ch,int len);CharNum *Merge(CharNum *AC,CharNum *BD,CharNum *ABDC,int k,int flagABDC);void MergeAdd(CharNum *des,CharNum *source,int k);void MergeMinus(CharNum *des,CharNum *source,int k);CharNum *Multiple(CharNum *X,CharNum *Y);void ShowCharNum(CharNum *Result);void ToChars(int mul,CharNum *Result);void TopDown(CharNum *chN);char *ToStr(CharNum *chN);//----end of method declaration----- //-------------the main method--------------int main(){CharNum *X;CharNum *Y;CharNum *Result; //init    X=NULL;Y=NULL;Result=NULL; //get X,YX=GetNum('X');Y=GetNum('Y'); Result=Multiple(X,Y);ShowCharNum(Result); free(X);free(Y);free(Result); getchar(); return 0;}//------------------the end of main method------------------  //-----------begin the method of TopDown---------------void TopDown(CharNum *chN){int i;int j;int k;char *ch; j=chN->len-1;while(chN->cptr[j]!='#'){j--;} ch=(char *)malloc(j*sizeof(char)); k=j-1;i=0;for(i,k;i<j;k--,i++){ch[i]=chN->cptr[k];}i=0;for(i;i<j;i++){chN->cptr[i]=ch[i];} free(ch);}//-----------end of method TopDown-------------- //-----------implement the method of getNum-------------CharNum *GetNum(char ch){ CharNum *chN;chN=(CharNum *)malloc(sizeof(CharNum));chN->cptr=NULL;chN->len=0; chN->cptr=(char *)malloc(MAX_LENGTH*sizeof(char));Init(chN->cptr,MAX_LENGTH);chN->len=MAX_LENGTH;printf("Input the value of %c(length<=)",ch);printf("%d",MAX_LENGTH-2);printf(" teminated by '#'):"); scanf("%s",chN->cptr); if(strlen(chN->cptr)>(MAX_LENGTH-2)){chN->cptr[MAX_LENGTH-2]='#';chN->cptr[MAX_LENGTH-1]='/0';} TopDown(chN); DelHeadZero(chN);chN->len=chN->len-1;    //delete the end '/0' characterchN->len=chN->len-1;    //delete the end '#' character return chN; }//-------------end of method getNum---------------- //-------------begin of method ToStr--------------char *ToStr(CharNum *chN){int i;char *str=(char *)malloc((chN->len+1)*sizeof(char));i=0;for(i;i<chN->len;i++){str[i]=chN->cptr[i];}str[chN->len]='/0';return str;}//-----------------end of method ToStr-------------- //-----------------begin of method DelHeadZero------------void DelHeadZero(CharNum *Result){int i;i=Result->len-1;for(i;i>=0;i--){if(Result->cptr[i]=='0'){Result->len--;}else{break;}}}//-----------------end of method DelHeadZero-------- //-----------------begin of method ToChars----------void ToChars(int mul,CharNum *Result){//the max length of DoMutiple's result length is 2Result->cptr[0]=mul%10+'0';Result->cptr[1]=mul/10+'0'; DelHeadZero(Result);}//-----------------end of method ToChars--------------  //-------------begin of method DoMultiple---------CharNum *DoMultiple(CharNum *X,CharNum *Y){char *chx;char *chy;CharNum *Result;int inx;int iny;int mul; chx=NULL;chy=NULL; chx=ToStr(X);chy=ToStr(Y); inx=atoi(chx);  //atoi() need the '/0' character, so ToStr()iny=atoi(chy);mul=inx*iny; Result=(CharNum *)malloc(sizeof(CharNum));Result->len=X->len+Y->len;Result->cptr=(char *)malloc((Result->len)*sizeof(char)); ToChars(mul,Result); free(chx);free(chy); return Result;}//-----------------end of method DoMultiple---------------- //-----------------begin method GetMax----------------int GetMax(int x,int y){return(x>=y?x:y);}//-----------------end method GetMax------------- //-----------------begin method GetMin----------int GetMin(int x,int y){return(x>=y?y:x);}//-----------------end of method GetMin---------------  //-----------------begin of method Init------------void Init(char *ch,int len){int i=0;for(i;i<len;i++){ch[i]='0';}}//----------------end of method Init----------------- //------------------begin of method DoMinus----------CharNum *DoMinus(CharNum *A,CharNum *B,int *flag){CharNum *Result;int i;char *cha;char *chb;int flags; Result=(CharNum *)malloc(sizeof(CharNum));Result->len=GetMax(A->len,B->len);Result->cptr=(char *)malloc((Result->len)*sizeof(char)); cha=(char *)malloc((Result->len)*sizeof(char));chb=(char *)malloc((Result->len)*sizeof(char));   Init(Result->cptr,Result->len);Init(cha,Result->len);Init(chb,Result->len); i=0;for(i;i<A->len;i++){cha[i]=A->cptr[i];}i=0;for(i;i<B->len;i++){chb[i]=B->cptr[i];} i=0;flags=0;for(i;i<Result->len;i++){if(cha[i]-chb[i]-flags>=0){Result->cptr[i]=cha[i]-chb[i]-flags+'0';flags=0;}else{Result->cptr[i]=10+cha[i]-chb[i]-flags+'0';if(i<Result->len-1){flags=1;}else{*flag=1;}}} // if(*flag==1)get the negative valueif((*flag)==1){ Init(Result->cptr,Result->len);i=0;   flags=0;    for(i;i<Result->len;i++){if(chb[i]-cha[i]-flags>=0){Result->cptr[i]=chb[i]-cha[i]-flags+'0';flags=0;}else{Result->cptr[i]=10+chb[i]-cha[i]-flags+'0';   flags=1;}}} free(cha);free(chb); DelHeadZero(Result); return Result;}//-----------------end of method DoMinus-----------------  //---------------begin of method MergeAdd---------------void MergeAdd(CharNum *des,CharNum *source,int k){int flags;int i; i=k;flags=0;for(i;i<k+source->len;i++){if((source->cptr[i-k]-'0')+(des->cptr[i]-'0')+flags>=10){des->cptr[i]=source->cptr[i-k]+(des->cptr[i]-'0')+flags-10;flags=1;}else{des->cptr[i]=source->cptr[i-k]+(des->cptr[i]-'0')+flags;flags=0; }}des->cptr[k+source->len]=des->cptr[k+source->len]+flags; }//-----------------end of method MergeAdd-----------------------------  //-----------------begin of method MergeMinus------------------------void MergeMinus(CharNum *des,CharNum *source,int k){int flags;int i; i=k;flags=0;for(i;i<k+source->len;i++){if((des->cptr[i])-(source->cptr[i-k])-flags>=0){des->cptr[i]=(des->cptr[i])-(source->cptr[i-k])-flags+'0';flags=0;}else{des->cptr[i]=10+(des->cptr[i])-(source->cptr[i-k])-flags+'0';flags=1;}} i=k+source->len;for(i;i<des->len;i++){if(des->cptr[i]-'0'-flags>=0){des->cptr[i]=des->cptr[i]-flags;flags=0;}else{des->cptr[i]=des->cptr[i]-flags+10;flags=1;}}}//----------------end of method MergeMinus------------  //-----------------begin of method Merger-------------CharNum *Merge(CharNum *AC,CharNum *BD,CharNum *ABDC,int k,int flagABDC){CharNum *Result;int len;int i; len=AC->len+2*k+1; Result=(CharNum *)malloc(sizeof(CharNum));Result->len=len;Result->cptr=(char *)malloc(len*sizeof(char)); Init(Result->cptr,len); i=0; MergeAdd(Result,BD,0);MergeAdd(Result,BD,k);MergeAdd(Result,AC,k);MergeAdd(Result,AC,2*k); if(0==flagABDC){MergeAdd(Result,ABDC,k);}if(1==flagABDC){MergeMinus(Result,ABDC,k);} DelHeadZero(Result); return Result;}//------------------end of method Merge--------------   //-------------begin of method Multiple--------------CharNum *Multiple(CharNum *X,CharNum *Y){CharNum *Result;CharNum *A,*B,*C,*D;CharNum *AC,*BD,*A_B,*D_C,*ABDC;int k;int flag[3]={0};//flag[0] represent the sign of (A-B)  ,               //flag[1]--(D-C),flag[2]--(A-B)(D-C) //initResult=NULL; A=(CharNum *)malloc(sizeof(CharNum));A->cptr=NULL;A->len=0;B=(CharNum *)malloc(sizeof(CharNum));B->cptr=NULL;B->len=0;C=(CharNum *)malloc(sizeof(CharNum));C->cptr=NULL;C->len=0;D=(CharNum *)malloc(sizeof(CharNum));D->cptr=NULL;D->len=0; AC=NULL;BD=NULL;A_B=NULL;D_C=NULL;ABDC=NULL; if((X->len==0)||(Y->len==0)){Result=(CharNum *)malloc(sizeof(CharNum));Result->cptr=NULL;Result->len=0;return Result;}else if((X->len==1)&&(Y->len==1)){Result=DoMultiple(X,Y);}else{k=(GetMax(X->len,Y->len)-1)/2+1;if(k<GetMin(X->len,Y->len)){  A->cptr=&(X->cptr[k]);A->len=X->len-k; B->cptr=X->cptr;B->len=k;DelHeadZero(B); C->cptr=&(Y->cptr[k]);C->len=Y->len-k; D->cptr=Y->cptr;D->len=k;DelHeadZero(D); }else if(k>=X->len){B->cptr=X->cptr;B->len=X->len;DelHeadZero(B); C->cptr=&(Y->cptr[k]);C->len=Y->len-k; D->cptr=Y->cptr;D->len=k;DelHeadZero(D);}else if(k>=Y->len){A->cptr=&(X->cptr[k]);A->len=X->len-k; B->cptr=X->cptr;B->len=k;DelHeadZero(B);D->cptr=Y->cptr;D->len=k;DelHeadZero(D);} AC=Multiple(A,C);BD=Multiple(B,D);A_B=DoMinus(A,B,&flag[0]);D_C=DoMinus(D,C,&flag[1]);ABDC=Multiple(A_B,D_C); if(flag[0]!=flag[1]){flag[2]=1;} Result=Merge(AC,BD,ABDC,k,flag[2]); } //free the memoryfree(A);free(B);free(C);free(D);free(AC);free(BD);free(A_B);free(D_C);free(ABDC);return Result;}//--------------------end of method Multiple----------------------- //--------------------begin of method ShowCharNum-------------void ShowCharNum(CharNum *Result){int i; printf("The multiple result is: "); i=Result->len-1;for(i;i>=0;i--){printf("%c",Result->cptr[i]);}printf("/n");}//--------------------end of method ShowCharNum-----------------