1. 程式人生 > >同一個問題有多個解

同一個問題有多個解

lean color 自帶 this math.sqrt code clas spa tar

https://www.codewars.com/kata/5592e3bd57b64d00f3000047

做這道kata時,有個變量的比較運算符寫錯了,應該設置為< ,而我設置的 != ,(更正後↓完全正確)

public static long findNb0(long m) {
        long n = 0;// 求得的n
        long sum = 0;// 累加值與m進行判定
        long s = 0;
        boolean rightN = false;
        while (s < m) {
            sum += (s * s * s);

            
if (sum == m) { rightN = true; n = s; break; } if (sum > m) { break; } s++; } if (rightN) { return n; } else { return -1; } }

它(this kata)求的是按照1的立方,2的立方,3的立方這樣的累加一直到n的立方,是否等於傳入的m. 返回數值n.

很簡單的想法是可以使用遞增, 將 n*n*n 去 ++ .就像上面的寫法,看了下CW大神的解法:

    public static long findNb2(long m) {
        long mm = 0, n = 0;
        while (mm < m)
            mm += ++n * n * n;
        return mm == m ? n : -1;
    }

寫法更加簡練了,但其實還是一個道理,就是遞增,我在想應該有更快速的方式(因為之前做類似的題時,使用遞增這樣做法會超時(也就是所說的算法的時間復雜度過高了))

使用java自帶的Math類方法:(但不完全正確,通過率98%),除了Math類計算失誤(不支持大數值),之下的解答邏輯性應無誤(98%確定)

public static long findNb(long m) {

        double x = Math.sqrt(m); << 問題出在這裏,應該為有小數的結果會可能返回正整數
        if (x != (Math.round(x))) {   
            return -1;
        }

        long n = (long) (Math.floor(Math.sqrt(x * 2)));
        return n;

    }

最後經過多方論證,規律尋找,覺得這個解法是可以的,但是大多數測試通過了,有幾個是通過不了的,而且都是數值非常大的情況下,

最終經過計算,得出結論: java自帶的算術式以及支持的數值大小不能做這道題,如果支持的數值大小可以滿足時,這種做法是對的.

但是這還不是最終結論.

但對於18位數值是可以的.19位就不準了.

再次我驗證:

使用 遞增的方式 s*s*s.

使用有平方根的數值:

long m = 1667089848622288897L;

這裏很奇妙的是,使用百度的求平方根,對於這個數,以及這個數-1的數,結果是一樣的.(問題就出在這個地方)

遞增後查看結果:

......
......
......
1666827415525457025
1666958628200550400
1667089848622288896
1667221076790977409
-1

最後當最後long值超過其本身後,返回了-1.(表示沒有n)

那麽這裏的超過之前的數值1667089848622288896 是小於m (1) 個大小的.

這裏的疑問是:

>> 也許是java中的Math類計算失誤(對於過大數值)

>> 或者是計算機底層的相乘出錯了?(相乘使用的其實是加法),

>> 也許是我寫的解答就是不對的?(對於有整型平方根的整數,其是有13+23+33+......+n3的和一樣的整數的這件事情,我覺得應該沒問題,畢竟測試通過率為98%(當然除了這個數值和其它更大數值))

那麽究竟是long值相乘計算出錯了還是Math.sqrt的求開方出錯了,這個只能在更強有力的計算機上去嘗試了.(完全沒有譜了,要不然就拿張白紙挨個相乘...計算)

技術分享圖片

技術分享圖片

技術分享圖片

不太靠譜的百度,給出了不太靠譜的結論. (有病去醫院不要問百度)

最後我覺得先放一下這個問題,或者有哪位使用C語言的大神看到這道題,麻煩幫忙證明一下結果正確性??謝謝

待看 -> 實現超大整數(超過long長度範圍)的加法運算

-------------------------------------------------------長長的分割線,記錄下我對家的思念--------------------------------------------------------------

技術分享圖片

技術分享圖片

同一個問題有多個解