大數除法
阿新 • • 發佈:2018-08-10
基本 scan print 大數 \n 手工 功能 printf 形式
大數除法,應該算是四則運算裏面最難的一種了。不同於一般的模擬,除法操作步數模仿手工除法,而是利用減法操作實現的。 其基本思想是反復做除法,看從被除數裏面最多能減去多少個除數,商就是多少。 逐個減顯然太慢,要判斷一次最多能減少多少個整的10的n次方。 以7546除23為例。 先減去23的100倍,就是2300,可以減3次,余下646。 此時商就是300; 然後646減去23的10倍,就是230,可以減2次,余下186。此時商就是320; 然後186減去23,可以減8次,此時商就是328. 根據這個思想,不難寫出下面的代碼。 還是那句話,可能算法效率不是很高。但是常規解題思路一般就是這樣了。 #include<cstdio> #include<cstring> #include<cstdlib> #define MaxLen 200 //函數SubStract功能: //用長度為len1的大整數p1減去長度為len2的大整數p2 // 結果存在p1中,返回值代表結果的長度 //不夠減 返回-1 正好夠 返回0 int SubStract( int *p1, int *p2, int len1, int len2 ) { int i; if( len1 < len2 ) return -1; if( len1 == len2 ) { //判斷p1 > p2 for( i=len1-1; i>=0; i-- ) { if( p1[i] > p2[i] ) //若大,則滿足條件,可做減法 break; else if( p1[i] < p2[i] ) //否則返回-1 return -1; } } for( i=0; i<=len1-1; i++ ) //從低位開始做減法 { p1[i] -= p2[i]; if( p1[i] < 0 ) //若p1<0,則需要借位 { p1[i] += 10; //借1當10 p1[i+1]--; //高位減1 } } for( i=len1-1; i>=0; i-- ) //查找結果的最高位 if( p1[i] ) //最高位第一個不為0 return (i+1); //得到位數並返回 return 0; //兩數相等的時候返回0 } int main() { int n, k, i, j; //n:測試數據組數 int len1, len2; //大數位數 int nTimes; //兩大數相差位數 int nTemp; //Subtract函數返回值 int num_a[MaxLen]; //被除數 int num_b[MaxLen]; //除數 int num_c[MaxLen]; //商 char str1[MaxLen + 1]; //讀入的第一個大數 char str2[MaxLen + 1]; //讀入的第二個大數 scanf("%d",&n); while ( n-->0 ) { scanf("%s", str1); //以字符串形式讀入大數 scanf("%s", str2); for ( i=0; i<MaxLen; i++ ) //初始化清零操作 { num_a[i] = 0; num_b[i] = 0; num_c[i] = 0; } len1 = strlen(str1); //獲得大數的位數 len2 = strlen(str2); for( j=0, i=len1-1; i>=0; j++, i-- ) num_a[j] = str1[i] - ‘0‘; //將字符串轉換成對應的整數,顛倒存儲 for( j=0, i=len2-1; i>=0; j++, i-- ) num_b[j] = str2[i] - ‘0‘; if( len1 < len2 ) //如果被除數小於除數,結果為0 { printf("0\n"); continue; //利用continue直接跳出本次循環。 進入下一組測試 } nTimes = len1 - len2; //相差位數 for ( i=len1-1; i>=0; i-- ) //將除數擴大,使得除數和被除數位數相等 { if ( i>=nTimes ) num_b[i] = num_b[i-nTimes]; else //低位置0 num_b[i] = 0; } len2 = len1; for( j=0; j<=nTimes; j++ ) //重復調用,同時記錄減成功的次數,即為商 { while((nTemp = SubStract(num_a,num_b + j,len1,len2 - j)) >= 0) { len1 = nTemp; //結果長度 num_c[nTimes-j]++;//每成功減一次,將商的相應位加1 } } //輸出結果 for( i=MaxLen-1; num_c[i]==0 && i>=0; i-- );//跳過高位0 if( i>=0 ) for( ; i>=0; i-- ) printf("%d", num_c[i]); else printf("0"); printf("\n"); } return 0; }
大數除法