同一个问题有多个解

简介: https://www.codewars.com/kata/5592e3bd57b64d00f3000047 做这道kata时,有个变量的比较运算符写错了,应该设置为< ,而我设置的 != ,(更正后↓完全正确) public static long findNb0(long m) { ...

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语言的大神看到这道题,麻烦帮忙证明一下结果正确性谢谢

 

 

待看 -> 实现超大整数(超过long长度范围)的加法运算

 

 

 

 

 

 

-------------------------------------------------------长长的分割线,记录下我对家的思念--------------------------------------------------------------

 

将编程看作是一门艺术,而不单单是个技术。 敲打的英文字符是我的黑白琴键, 思维图纸画出的是我编写的五线谱。 当美妙的华章响起,现实通往二进制的大门即将被打开。
相关文章
|
2月前
|
消息中间件 Linux 容器
共享内存的创建和映射过程
【9月更文挑战第1天】消息队列、共享内存及信号量在使用前需生成key并获取唯一ID,均通过`xxxget`函数实现。
|
2月前
|
程序员 编译器
静态分配和动态分配之间的区别是什么
【9月更文挑战第1天】静态分配和动态分配之间的区别是什么
438 0
|
6月前
|
C++
C++程序对象动态建立和释放
C++程序对象动态建立和释放
48 1
|
6月前
|
C++
35对象的动态建立和释放
35对象的动态建立和释放
29 1
|
6月前
|
存储 Java
|
6月前
|
Java 关系型数据库 MySQL
【数据库连接,线程,ThreadLocal三者之间的关系】
【数据库连接,线程,ThreadLocal三者之间的关系】
91 0
|
6月前
|
C++
34共用数据的保护
34共用数据的保护
44 0
|
存储 缓存 小程序
小程序全局共享数据--存储
小程序全局共享数据--存储
91 0
|
IDE 开发工具
域对象共享数据~
域对象共享数据~
|
编译器 C语言 C++
【c++】 --- 对象的动态建立和释放
【c++】 --- 对象的动态建立和释放
49 0