日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

实现除法操作

發布時間:2025/3/19 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实现除法操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前文

  • 一道算法題,涉及到了二進制的位操作,借這個機會整理一下相關的知識點,并且在這道算法題中進行了實踐
  • 本文的解法來自于該算法題的一篇討論。

  • 一、算法題介紹

    對除數和被除數實現除法運算,其中不使用乘法、除法和求余操作,返回對應的商。如,
    Input: dividend = 10, divisor = 3
    Output: 3

    解法1:暴力解法

    class Solution {public int divide(int dividend, int divisor){//定義除法,被除數是最小值,除以-1時,是最大值if(dividend == Integer.MIN_VALUE && divisor == -1)return Integer.MAX_VALUE;//^運算符,只有不同時,才為true ; sign定義商是否為負數 int sign = (dividend < 0) ^ (divisor < 0) ? -1 : 1;int result = 0;//取除數和被除數的正數形式long x = Math.abs((long)dividend);long y = Math.abs((long)divisor);//統計被除數共減去多少個除數,即為商while(x >= y){x -= y;result++;}return sign > 0 ? result : -result;} } 復制代碼
  • 暴力解法主要是通過不斷循環將y(除數)從x(被除數)中減去,直到x<y. x減去y的次數就是商,而最后剩下的小于y的部分就是余數。暴力解法的時間復雜度很高,比如說,當x=231-1,y=1時,需要循環231-1次。
    • 時間復雜度:O(x),x是被除數。
    • 空間復雜度:O(1)。

    解法2:除數左移位累加

    class Solution {public int divide(int dividend, int divisor){if(dividend == Integer.MIN_VALUE && divisor == -1)return Integer.MAX_VALUE;int sign = (dividend < 0) ^ (divisor < 0) ? -1 : 1;int result = 0;long x = Math.abs((long)dividend);long y = Math.abs((long)divisor);while(x >= y){int shift = 1;//將y持續向左移位,相當于y*2^(shift);//當y*2^(shift)< x <y*2^(shift+1)時,循環結束while(x >= (y << shift)){shift++;}x -= y << (shift - 1);//相當于x = y*2^(shift)+y*2^(shift-n)+.....+y*2^(0) + m;m是余數result += 1 << (shift - 1);}return sign > 0 ? result : -result;} } 復制代碼
  • 這個方法,是計算最大的k,使得y*2k<=x,然后將y*2k從x中減去,將2k加到商里面。比如說, 如果x= (1011)2,y=(10)2,那么因為2*22<= 11而且2*23>11 所以k=2。所以,我們將 (1011)2減去 (1000)2得到 (11)2,然后,將2k=22=(100)2加到商中,然后將x更新為(11)2繼續運算。
  • 使用y*2k的優勢在于,可以使用非常高效的移位操作,而且每次循環后,最差的情況下,x都會變為原來的一半。如果n是x/y的商的位數,那么總共需要n次循環。子循環中每次通過循環k次來找到y*2k的最大的k,因此:
    • 時間復雜度:O(n2),n是x/y的商的位數。
    • 空間復雜度:O(1)。

    解法3:除數左移位遞減

    class Solution {public int divide(int dividend, int divisor){if(dividend == Integer.MIN_VALUE && divisor == -1)return Integer.MAX_VALUE;int sign = (dividend < 0) ^ (divisor < 0) ? -1 : 1;int result = 0;int power = 32;//long是8字節,64位;int是4字節,32位long x = Math.abs((long)dividend);long y = Math.abs((long)divisor);while(x >= y){//將y*2^32增加到最大,然后逐步減小,靠近x//y*2^power<x時結束while((y << power) > x){//每次只需要執行有限步就能找到power,不像前面中的方法,是執行O(n)步才能找到power--;}x -= y << power;result += 1 << power;}return sign > 0 ? result : -result;} } 復制代碼

    1.在每次循環中找到最大的k的最好的方式就是認識到k其實是在不斷縮小的。因此,我們不需要在每次子循環的時候都檢驗一下21,22,23......是否小于或者等于x,我們可以在找到最大的k后,直接在后面的每次循環中檢驗x和2k-1,2k-2,2k-3....的關系。
    2. 我們可以繼續之前的例子。商為(100)2后,我們繼續計算(11)2。因為y*2k<=x的最大k是0,所以我們把20=(1)2加到商里,因此商就變成了(101)2。然后我們繼續算法,因此(1)2<y,所以算法結束。最后,我們可以得到,x= (1011)2,y=(10)2相除,商為(101)2,余數為(1)2。

    • 時間復雜度:O(n),n是x/y的商的位數。
    • 空間復雜度:O(1)

    總結

    以上是生活随笔為你收集整理的实现除法操作的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。