我們把整數A由規模n分為n1和n2,把整數B由規模m分為m1和m2,如下圖:
則A分為n1位的A1和n2位的A1,B分為m1位的B1和m2位的B2,如下式所示:
以此類推,我們可以把A1、A2、B1、B2繼續划分,直至最小單位。(這里在編程時需要用遞歸來實現)
上面講的很清楚了,那么A和B的相乘就可以表示為:
#include <stdio.h> #include <malloc.h> #include <stdlib.h> #include <string.h> char *result = '\0'; int pr = 1; void getFill(char *a,char *b,int ia,int ja,int ib,int jb,int tbool,int move){ int r,m,n,s,j,t; char *stack; // get(a,b,0,0,0,0,1,2) m = a[ia] - 48; // m=1 if( tbool ){// 直接從結果數組的標志位填入,這里用了堆棧思想 這部分實現A1xB1 r = (jb - ib > ja - ia) ? (jb - ib) : (ja - ia); // r=0 stack = (char *)malloc(r + 4); // 因為執行了getFill方法,此時ia=ja,說明兩個數必定其中一個是個位數,而jb-ib的值+1即另一個數的位數 for(r = j = 0,s = jb; s >= ib; r ++,s --){ // r=j=s=0;0>=0;r++,s++ r=1,s=-1 n = b[s] - 48; // n=4 stack[r] = (m * n + j) % 10; //stack[0]=(1x4+0)%10=4 通過模10來獲取result[1]位置上的數 j = (m * n + j) / 10; // j=(1x4+0)/10 = 0 通過整除來獲取result[1]位置上的數,如果j=0,則只需要填寫result[1]位置的數;如果j不等於0,則將j放在 } // result[1]位置,前面取模獲取的值放在result[2]所在的位置 if( j ){ // 如果j 不等於0,如j=1,stack[1]=1,則將stack[1]賦值給result[1],將stack[0]賦值個result[2].由於先有stack[0],再有stack[1],而使用時先用 stack[r] = j; // stack[1]=1 stack[1]再用stack[0],即先進后出,所以說使用了棧的思想。 r ++; // r=2 } // r=1 for(r --; r >= 0; r --,pr ++) // r=0;0>=0; pr=2 result[pr] = stack[r]; //result[1]=stack[0]=4 free(stack); // move=2 pr=2 由於A1xB1之后后面還要加00,故將result[1]后面的兩個字節空間賦值為\0.字符串是以\0作為結束標志的,在內存中,比如字符串“abc”,實際上是4個字節的空間abc\0 for(move = move + pr; pr < move; pr ++) // move=4;2<4;pr++ pr=3 move=4;3<4;pr++ pr=4 result[pr] = '\0'; // result[2]='\0' result[3]='\0' } else{ //與結果的某幾位相加,這里不改變標志位 pr 的值 //這部分實現A2xB1,A1xB2,A2xB2 r = pr - move - 1; for(s = jb,j = 0; s >= ib; r --,s --){ n = b[s] - 48; t = m * n + j + result[r]; result[r] = t % 10; j = t / 10; } for( ; j ; r -- ){ t = j + result[r]; result[r] = t % 10; j = t / 10; } } } int get(char *a,char *b,int ia,int ja,int ib,int jb,int t,int move){ int m,n,s,j; if(ia == ja){ getFill(a,b,ia,ja,ib,jb,t,move); return 1; } else if(ib == jb){ getFill(b,a,ib,jb,ia,ja,t,move); return 1; } else{ // 12x45 get(a,b,0,1,0,1,1,0) m = (ja + ia) / 2; // m=0 n = (jb + ib) / 2; // m=0 s = ja - m; // s=1 j = jb - n; // j=1 get(a,b,ia,m,ib,n,t,s + j + move); // get(a,b,0,0,0,0,1,2) get(a,b,ia,m,n + 1,jb,0,s + move); // get(a,b,0,0,1,1,0,1) get(a,b,m + 1,ja,ib,n,0,j + move); // get(a,b,1,1,0,0,0,1) get(a,b,m + 1,ja,n + 1,jb,0,0 + move); // get(a,b,1,1,1,1,0,0) } return 0; } int main(){ char *a,*b; int n,flag; a = (char *)malloc(1000); // 分配所需的內存空間 1000字節 b = (char *)malloc(1000); printf("The program will computer a*b\n"); printf("Enter a b:"); scanf("%s %s",a,b); result = (char *)malloc(strlen(a) + strlen(b) + 2); flag = pr = 1; result[0] = '\0'; if(a[0] == '-' && b[0] == '-') get(a,b,1,strlen(a)-1,1,strlen(b)-1,1,0); if(a[0] == '-' && b[0] != '-'){ flag = 0; get(a,b,1,strlen(a)-1,0,strlen(b)-1,1,0); } if(a[0] != '-' && b[0] == '-'){ flag = 0; get(a,b,0,strlen(a)-1,1,strlen(b)-1,1,0); } if(a[0] != '-' && b[0] != '-') get(a,b,0,strlen(a)-1,0,strlen(b)-1,1,0); // get(a,b,0,1,0,1,1,0) if(!flag) printf("-"); if( result[0] ) printf("%d",result[0]); for(n = 1; n < pr ; n ++) printf("%d",result[n]); printf("\n"); free(a); free(b); free(result); system("pause"); return 0; }
void getFill(char *a,char *b,int ia,int ja,int ib,int jb,int tbool,int move){ int r,m,n,s,j,t; char *stack; // get(a,b,0,0,1,1,0,1) 計算A1xB2 m = a[ia] - 48; // m=1 m為A1的值 if( tbool ){// 直接從結果數組的標志位填入,這里用了堆棧思想 r = (jb - ib > ja - ia) ? (jb - ib) : (ja - ia); stack = (char *)malloc(r + 4); for(r = j = 0,s = jb; s >= ib; r ++,s --){ n = b[s] - 48; // n=4 stack[r] = (m * n + j) % 10; j = (m * n + j) / 10; } if( j ){ stack[r] = j; r ++; } for(r --; r >= 0; r --,pr ++) result[pr] = stack[r]; free(stack); for(move = move + pr; pr < move; pr ++) result[pr] = '\0'; } else{ //與結果的某幾位相加,這里不改變標志位 pr 的值 r = pr - move - 1; // pr=4 move=1 r=4-1-1=2 for(s = jb,j = 0; s >= ib; r --,s --){ // s=jb=1,j=0;1>=1;r--,s-- n = b[s] - 48; // n=5 n為B2的值 t = m * n + j + result[r]; // t=1*5+0+result[2]=5+0=5 result[r] = t % 10; // result[2]=5 將兩個數相乘的結果模10得到result[2]上的值, j = t / 10; // j=0 將兩個數相乘的結果整除10得到是否需要進一位, } // r=1,s=0 for( ; j ; r -- ){ t = j + result[r]; result[r] = t % 10; j = t / 10; } } } void getFill(char *a,char *b,int ia,int ja,int ib,int jb,int tbool,int move){ int r,m,n,s,j,t; char *stack; // get(a,b,1,1,0,0,0,1) 計算A2xB1 m = a[ia] - 48; // m=2 m為A2的值 if( tbool ){// 直接從結果數組的標志位填入,這里用了堆棧思想 r = (jb - ib > ja - ia) ? (jb - ib) : (ja - ia); stack = (char *)malloc(r + 4); for(r = j = 0,s = jb; s >= ib; r ++,s --){ n = b[s] - 48; stack[r] = (m * n + j) % 10; j = (m * n + j) / 10; } if( j ){ stack[r] = j; r ++; } // r=1 for(r --; r >= 0; r --,pr ++) result[pr] = stack[r]; free(stack); for(move = move + pr; pr < move; pr ++) result[pr] = '\0'; } else{ //與結果的某幾位相加,這里不改變標志位 pr 的值 r = pr - move - 1; // pr=4 move=1 r=4-1-1=2 for(s = jb,j = 0; s >= ib; r --,s --){ // s=jb=0,j=0;0>=0;r--,s-- n = b[s] - 48; // n=4 n為B1的值 t = m * n + j + result[r]; // t=2*4+0+result[2]=8+5=13 兩個數相乘的結果加上前面A1xB2的結果 result[r] = t % 10; // result[2]=3 將兩個數相乘的結果加上前面A1xB2的結果模10得到最后result[2]的值 j = t / 10; // j=1 r=1 s=-1 整除10看是否需要進一位,如果需要進一位,則將j與原來result[1]相加,result[1]再對10取模,即可確定result[1]的值 } // r=1,s=-1 for( ; j ; r -- ){ t = j + result[r]; // t=1+4=5 result[r] = t % 10; // result[1]=5 j = t / 10; // j=0 r=0 } } } void getFill(char *a,char *b,int ia,int ja,int ib,int jb,int tbool,int move){ int r,m,n,s,j,t; char *stack; // get(a,b,1,1,1,1,0,0) 計算A2xB2 m = a[ia] - 48; // m=2 m為A2的值 if( tbool ){// 直接從結果數組的標志位填入,這里用了堆棧思想 r = (jb - ib > ja - ia) ? (jb - ib) : (ja - ia); stack = (char *)malloc(r + 4); for(r = j = 0,s = jb; s >= ib; r ++,s --){ n = b[s] - 48; stack[r] = (m * n + j) % 10; j = (m * n + j) / 10; } if( j ){ stack[r] = j; r ++; } for(r --; r >= 0; r --,pr ++) result[pr] = stack[r]; free(stack); for(move = move + pr; pr < move; pr ++) result[pr] = '\0'; } else{ //與結果的某幾位相加,這里不改變標志位 pr 的值 r = pr - move - 1; // pr=4 move=0 r=4-0-1=3 for(s = jb,j = 0; s >= ib; r --,s --){ // s=jb=1,j=0;1>=1;r--,s-- n = b[s] - 48; // n=5 n為B2的值 t = m * n + j + result[r]; // t=2*5+0+result[3]=10+0=10 將兩個數相乘再加上原來這個位置的值 result[r] = t % 10; // result[3]=0 模10得到這個位置上的值, j = t / 10; // j=1 r=2 s=0 整除10看是否需要進一位,如果需要進一位,則j+result[2]得到最終的值 } // r=2,s=-1 for( ; j ; r -- ){ t = j + result[r]; // t=1+result[2]=1+3=4 result[r] = t % 10; // result[2]=4 j = t / 10; // j=0 r=1 } } }
總結:
get(a,b,0,0,0,0,1,2) 1x4 00 result[1]=4(初值)
get(a,b,0,0,1,1,0,1) 1x5 0 result[2]=5(初值)
get(a,b,1,1,0,0,0,1) 2x4 0 result[2]=3(初值) result[1]=5 (終值)
get(a,b,1,1,1,1,0,0) 2x5 result[3]=0(終值) result[2]=4(終值)