检查中的调试问题,老巫师邪教谜语

debug problem in the checking, old wizards cult riddle

我正在尝试解决 java 中的这个谜语,关于一个老人,他活着是因为他的邪教给了老人一些生命,这个特定的代码应该符合给定的规则但是测试中的一项检查是错误的。

public class hello {
    /** set true to enable debug */
    static boolean debug = true;

    static long old(int n, int m, int k, int newp) {
            int max;
            int min;
        boolean moreRows;

    if (m > n) {
        min = n;
        max = m;
        moreRows = true;
    } else {
        min = m;
        moreRows = false;
        max = n;
    }
    int sum = 0;
    int[][] ar2 = new int[(int)m][(int)n];
    // square part
    for (int i = 0; i < min; i++) {
        for (int j = 0; j < i; j++) {
           int t = i ^ j;
            ar2[i][j] = t - (t >= k ? k : 0);;
            sum += 2 * t- (t >= k ? k : 0);;
        }
    }
    for (int i = min; i < max; i++) {
        for (int j = 0; j < min; j++) {
            int t = i ^ j;
            sum += t;
            if (moreRows) {
                ar2[i][j] = t - (t >= k ? k : 0);
            } else {
                ar2[j][i] = t;
            }
        }
    }
        //retrun time
            while(newp<sum && newp>0) {
                sum=sum-newp;//wrap it up
            }
            return sum;
    }
  }

这是包含多个示例的断言等于测试:

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

public class HelloTest {

    @Test
    public void example() {
        assertEquals(5, Hello.olde(8, 5, 1, 100));
        assertEquals(224, Hello.old(8, 8, 0, 100007));
        assertEquals(11925, Hello.old(25, 31, 0, 100007));
        assertEquals(4323, Hello.old(5, 45, 3, 1000007));
        assertEquals(1586,Hello.old(31, 39, 7, 2345));
        assertEquals(808451, Hello.old(545, 435, 342, 1000007));
        // You need to run this test very quickly before attempting the actual tests :)
        assertEquals(5456283, Hello.old(28827050410L, 35165045587L, 7109602, 13719506));
    }

}

我收到以下错误,看起来像一个 long to int-

./src/test/java/HelloTest.java:19: error: incompatible types: possible lossy conversion from long to int
        assertEquals(5456283, hello.old(28827050410L, 35165045587L, 7109602, 13719506));
                                                ^
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error

来自较难示例的更多错误-

        assertEquals(5456283, Hello.old(28827050410L, 35165045587L, 7109602, 13719506));
                                                ^
./src/test/java/HelloTest.java:39: error: incompatible types: possible lossy conversion from long to int
            long expected = Hello.old(m, n, l, t), actual = Hello.old(m, n, l, t);

调试其中一个断言等于和更难的示例中的一些错误,我真的想不出可以更改什么,我确定它很小,因此将不胜感激-注意:t永远不会大于 2^32 - 1(根据问题的说明) 谢谢

据我所知,数组的大小不能超过 int,但如果您不想在任何地方都更改 long,您可以添加 cast。

long m = 434;
    int[] obj = new int[(int) m];

尝试通过与数组关联的迭代器访问超出允许的最大值可能会导致 OutOfMemoryExceptionIndexOutOfBoundsExceptionNoSuchElementException 之一,具体取决于实现。

这是一种非常不切实际的内存使用方式。如果想要这样的数据结构,应该研究 RAM 密集度较低的方法,例如数据库、稀疏数组等。

  1. 最后的测试不会 运行 在一台机器上,因为 long 值不能用作数组长度和索引。这已经在 answer/comments 中解释给您的

但是从任务中可以推导出,你根本不需要在数组中存储中间数据,你应该只计算总数。

即使不使用数组,也很可能需要 时间 来完成 [=14] 的嵌套循环=] 迭代。如果你有一个性能为 100 GFlop/s 的处理器,它应该能够在超过 160 年内计算出来。

  1. tsum的计算不正确。

应该是:

int t = i ^ j;
if (t >= k) {
    t -= k;
}
sum += 2 * t; // or sum += t in the second part.
  1. 最后一个循环似乎可以用简单的 return sum % newp;
  2. 代替

更新:

函数 old 可以重构如下(以摆脱数组),尽管它仍然是一个“幼稚”的解决方案,不会通过最后的测试。

static int old(int n, int m, int k, int newp) {
    int max;
    int min;

    if (m > n) {
        min = n;
        max = m;
    } else {
        min = m;
        max = n;
    }
    int sum = 0;
    // square part
    for (int i = 0; i < min; i++) {
        for (int j = 0; j < i; j++) {
            int t = i ^ j;
            if (t >= k) {
                t -= k;
                sum += 2 * t;
            }            
        }
    }
    for (int i = min; i < max; i++) {
        for (int j = 0; j < min; j++) {
            int t = i ^ j;
            if (t >= k) {
                t -= k;
                sum += t;
            }
        }
    }
    return sum % newp;
}

6 次测试的输出:

OK! 5
OK! 224
OK! 11925
OK! 4323
OK! 1586
OK! 808451