大數除法,本人認為是我目前見過大數演算法中最難的乙個(僅僅是個人想法),它與之前的大數加法乘法減法不同,有些難理解,下面我一點一點的分析,講解一下如何去實現大數除法。
首先,我們要知道除法中,存在四個常用名稱,被除數,除數,商,餘數(例如:53 / 8 = 6 餘 5 ;其中53 為被除數,8為除數,6為商,5為餘數 )當然我們可能會要求直接得到商,保留幾位小數(如:53 / 8 = 6.625)我們可以發現實際上小數部分0.625就是餘數除以除數的結果(5 / 8 = 0.625 ),所以在之後的討論中,我們只討論如何得到商和餘數。
一般我們在做除法問題時,也就是說資料型別之內的數之間的除法運算,我們一般會這樣去寫:
#includeint main()
}printf("商:%lld\n餘數:%lld\n",mer,rem);
}return 0;
}
這是除法的一般方法,我們在計算的時候,首先要考慮,輸入的被除數是否比除數大,如果比除數小或者兩數相等,那麼就可以直接得到商和餘數了,這就不用在解釋了吧,如果被除數比除數大,那麼我們就把被除數放迴圈裡,每次減1,直到能與除數整除。這是常規做法,是有限制的,我們所遇到的數必須是long long型別以內的數,如果比long long 大,就沒辦法算了。怎麼辦呢???
下面步入正題。。。。
由之前大數加法減法乘法中,我們可以知道,我們將大數以字串的形式輸入,然後再轉化為數字,下面我擷取了這部分**,我們可以看到,首先以字串的形式輸入兩個大數,然後分別得出兩個大數的位數,最後再利用陣列去倒序儲存字串中的每乙個元素,並轉化為數字,比如我之前舉例說明的 53 和 8 ,那麼存到陣列中就是 x[0]=3,x[1]=5; y[0]=8; 當然你也可以不倒置,直接順序讀入,但是在後面的計算過程中就會有一些變化,比如說得到的結果,倒置之後得到結果要去除前導0,不倒置得到的結果要去除字尾0。
while(~scanf("%s %s",a,b))
for(i=len2-1,k=0;i>=0;i--)
目前,我們要知道,在大數里我們已經不能再用剛才的常規方法去計算了,那怎麼去計算呢?這就需要轉一下腦子了,將剛才的除法思想轉變為減法思想,舉個栗子:(一般我們計算7除以2等於3餘1( 7 / 2 = 3 餘 1)),現在變成減法思想( 7 / 2 → 7 - 2 - 2 - 2 = 1 →減了3次,1比2小,不能再減了,即得到 7 / 2 = 3 餘 1)怎麼樣?腦子轉過來了嗎?如果還不行,你再用其他例子試試,理解了再往下看
現在我們就將除法變成減法了(開始上車了),再用 550 和 24 拿過來舉個栗子( 550-24-24-24-....-24 = 22)一共減了22次24,最後餘22,你可能會說,這太暴力了吧,哈哈哈哈哈,當然不啊,下面請看下圖:
( 550 / 24 = 22 餘 22 )(開始開車了),通過上圖,你發現了什麼?商為22,我們減了4次24,百位數字減兩次,十位數字減兩次,最後餘22,這就比開始我們減了22次要快多了吧。所以我們只需要使 被除數與除數字數相同,然後相減就可以了,(例如550 - 240 -240 - 24 - 24 = 22),位數不同時在除數後面補0。例如: 53 - 8,要用5-8,先補位,變成53-80,因為倒置了,即35-08,最後計算過後得到的結果是商為06,餘數為05,去除字首0 ,就得到最終結果了。
如果你理解了上面的思路,那麼現在咱們來詳細的分析一下大數除法的實現過程:
首先,要定義兩個字串來儲存大數,另外還需要兩個陣列來轉化之後的被除數,除數,並且再定義兩個陣列來儲存商和餘數。好了,開始輸入兩個大數,然後計算兩個大數的位數,分別用len1,len2儲存。之後開始將字串轉化為數字。
然後,我們就要判斷利用位數的大小來判斷被除數和除數的大小,如果len1然後就開始進入計算過程,首先初始化表示商的陣列(z[ ]),然後就判斷兩個數之間的關係以及位數與除數字數的關係,滿足條件,進行減法運算,若不滿足條件,將除數字數減1,即去0,迴圈直到得出結果。
4. 對得到的結果進行去除字首0操作,輸出結果。
**如下:
#include#includechar a[100],b[100];//用兩個字串用來輸入兩個大數
int x[100],y[100],z[100],m[100];//被除數 除數 商 餘數
int digit; //大數的位數
void sub(int x,int y,int len1,int len2)//大數減法
}}int judge(int x,int y,int len1,int len2)
for(i=len2-1,k=0;i>=0;i--)
if(len1=0;i--)//將除數後補零,使得兩個大數字數相同。
len2=len1;//將兩個大數數字相同
digit=len1; //將原被除數字數賦值給digit
for(j=0;j<=len;j++)
for(;i>=0;i--)
printf("%d",z[i]);
printf("\n");
printf("餘數是:");
for(i=len1;i>0;i--)
for(;i>=0;i--)
printf("%d",x[i]);
printf("\n");}}
return 0;
}
大數加法:
大數減法:
大數乘法:
BFS例項超詳細講解
例項參考挑戰程式設計bfs的迷宮最短路徑 include define maxn 100 using namespace std const int inf 100000000 typedef pairp 定義乙個pair型別的資料結構 char maze maxn maxn 1 定義乙個儲存輸入資...
迴圈佇列超詳細講解
迴圈佇列 佇列是我們常見的一種資料結構,他的特點就是先進先出fifo,而常見的佇列的效能不能實現所有的空間都被合理的應用,所以就出現的了我們的迴圈佇列 在這裡插入描述 這裡我們需要先了解幾個資料的含義 class circlequeue public boolean isfull public bo...
超詳細的Flex布局講解
應用在 flex items上的 css 屬性 flex布局是目前web開發中使用最多的布局方案 兩個重要的概念 開啟flex布局的方法 flex布局的相容性 注意 預設情況下felx items 僅在一行中顯示,若是設定flex wrap設定為多行,那麼,當flex items 到達main en...