前言
本期我們分享用C語言實現高精度除法,可通過該題測試點我點我,洛谷 p2005。
那么話不多說我們開始吧。
講解
大家還記不記得小學的時候我們是怎么做除法的?我們以111÷5為例。
我們的高精度除法也將采用這個思路進行,分別用兩個數組儲存數字a和b的值,翻轉后,從相對最高位開始相除,雖然我們不好實現除法,但是我們可以實現減法,比如11÷5可以理解為11-5-5這樣商就是2余數就是1,也就是所我們可以弄一個減法的循環直到不能再減就退出循環。那么我們在相減之前就需要判斷兩者的大小,比如1和5明顯沒法再減了,我們就需要跳到下一位再重新進行減法循環。
大致的思路就是這樣,下面我們用代碼講解:
#include <stdio.h>
#include<string.h>
char arra[20000] = { 0 }, arrb[20000] = { 0 };//分別儲存a,b的值
int ans[20000] = { 0 };//儲存商
int judge(char* arr1, char* arr2, int len)//判斷是否可以相減的函數
{if (arr1[len] >'0') return 1; //如果arr1比arr2長, 則可以除 for (int i = len - 1; i >= 0; i--) {//從arr的最高位開始與arr2比較 if (arr1[i] > arr2[i]) return 1;//相同位時arr1中的數字更大,則可以相除else if (arr1[i] < arr2[i]) return 0;//相同位時arr1數字更小則不能相除}return 1;//arr1和arr2完全一樣,可以相除
}
void my_reverse(char* arr, int len)//翻轉函數
{for (int i = 0; i < len - 1; i++, len--){char temp = arr[i];arr[i] = arr[len - 1];arr[len - 1] = temp;}
}
void print_div(int len1, int len2, char* arr1, char* arr2, int* ans)
{for(int i = len1-len2;i>=0;i--)//從最高位開始{while (judge(arr1 + i, arr2, len2))//判定是否可以相減{for (int j = 0; j < len2; j++)//高精度減法{if (arr1[i + j] < arr2[j]){arr1[i + j + 1] -= 1;arr1[i + j] += 10;}arr1[i + j] -= (arr2[j] - '0');}ans[i]++;//ans[i]不可能>10}}int len_ans = len1 - len2;//ans的長度while (arr1[len1] == '0' && len1 > 0) len1--;//去掉前綴無用的零 while (ans[len_ans] == 0 && len_ans > 0) len_ans--;for (int i = len_ans; i >= 0; i--)//打印商{printf("%d", ans[i]);}printf("\n");//如果想要得到余數,則直接打印arr1即可,此時arr1存儲的正是余數需要余數直接把下面的注釋消掉即可//if (len1 > 0||arr1[0]>='0')// for (int i = len1 - 1; i >= 0; i--)// printf("%c", arr1[i]);
}
int main()
{scanf("%s %s", arra, arrb);int lena = strlen(arra);//計算a和b的長度int lenb = strlen(arrb);my_reverse(arra, lena);my_reverse(arrb, lenb);print_div(lena, lenb, arra, arrb, ans);return 0;
}