同一个问题有多个解

Posted 整理是一切的开始

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了同一个问题有多个解相关的知识,希望对你有一定的参考价值。

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类计算失误(对于过大数值)

>> 或者是计算机底层的相乘出错了?(相乘使用的其实是加法),

>> 也许是我写的解答就是不对的?(对于有整型平方根的整数,其是有1³+2³+3³+......+n³的和一样的整数的这件事情,我觉得应该没问题,毕竟测试通过率为98%(当然除了这个数值和其它更大数值))

 

那么究竟是long值相乘计算出错了还是Math.sqrt的求开方出错了,这个只能在更强有力的计算机上去尝试了.(完全没有谱了,要不然就拿张白纸挨个相乘...计算)

不太靠谱的百度,给出了不太靠谱的结论. (有病去医院不要问百度)

最后我觉得先放一下这个问题,或者有哪位使用C语言的大神看到这道题,麻烦帮忙证明一下结果正确性

以上是关于同一个问题有多个解的主要内容,如果未能解决你的问题,请参考以下文章

Android - 一个选项卡中的多个片段

如何正确地将多个片段添加到片段过渡?

从单个按钮从多个片段中提取数据

php 在Yoast SEO中更改或删除OpenGraph输出的代码片段。此代码中有多个代码段。

kotlin-从一个片段更改多个片段的小数位

Chrome-Devtools代码片段中的多个JS库