【问题标题】:Pascal's triangle faulty output帕斯卡三角错误输出
【发布时间】:2016-11-14 18:46:48
【问题描述】:

您好,我正在用 Java 制作一个迭代的帕斯卡三角形。到目前为止一切正常,直到行数超过 13。输出出现故障。我一定是在这里做错了,请帮忙。

迭代帕斯卡:

public class IterativePascal extends ErrorPascal implements Pascal {
    private int n;
    IterativePascal(int n) throws Exception {
        super(n);
        this.n = n;
    }
    public void printPascal() {
        printPascal(false);
    }

    public void printPascal(boolean upsideDown) {
        if (n == 0) { return; }
        for (int j = 0; j <= n; j++) {
            for (int i = 0; i < j; i++) {
                System.out.print(binom(j - 1, i) + (j == i + 1 ? "\n" : " "));
            }
        }
    }

    public long binom(int n, int k) {
        return (k == 0 || n == k) ? 1 : faculty(n) / (faculty(k) * faculty(n - k));
    }

    private long faculty(int n) {
        if (n == 0 || n == 1) { return 1; }
        int result = 1;
        for (int i = 2; i <= n; i++) {
            result = result * i;
        }
        return result;
    }
}

输出:

1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
1 12 66 220 495 792 924 792 495 220 66 12 1
1 4 24 88 221 399 532 532 399 221 88 24 4 1 <----- wrong
1 0 1 5 14 29 44 50 44 29 14 5 1 0 1 <----- wrong

由于我是算法新手,因此会得到帮助。

【问题讨论】:

  • 我确信真正的爱因斯坦不会称其为“教师”:-) 您或您的拼写校正软件正在寻找的词是“阶乘”。

标签: java arrays algorithm pascals-triangle


【解决方案1】:

您正在达到数字溢出。因为14!太大了java里填不上long

解决方案是使用+ 而不是!

将您的三角形保留为 2D 数组并遍历它。每个单元格应该是两个“以上”的总和。

+---+---+---+---+
| 1 |   |   |   |
| 1 | 1 |   |   |
| 1 | 2 | 1 |   |
| 1 | 3 | 3 | 1 |
+---+---+---+---+

代码如下:

public static void triangle(int n) {
    int[][] triangle = new int[n];
    for (int i = 0; i < n; i++) {
        triangle[i] = new int[i+1];
    }
    triangle[0][0] = 1;
    triangle[1][0] = 1;
    triangle[1][1] = 1;
    for (int i = 2; i < n; i++) {
        triangle[i][0] = 1;
        for (int j = 1; j < triangle[i].length - 1; j++) {
            triangle[i][j] = triangle[i-1][j] + triangle[i-1][j+1];
        }
        triangle[i][triangle[i].length-1] = 1;
    }
    printArray(triangle);
}

编辑:
由于 OP 需要使用 binoms 进行递归解决方案,因此我决定添加引入 BigIntegers 的解决方案,因为它可能是这种情况。

public BigInteger binom(int n, int k) {
        return (k == 0 || n == k) ? BigInteger.ONE : faculty(n).divide((faculty(k).multiple(faculty(n - k)));
    }

private BigInteger faculty(int n) {
    BigInteger result = BigInteger.ONE;
    while (!n.equals(BigInteger.ZERO)) {
        result = result.multiply(n);
        n = n.subtract(BigInteger.ONE);
    }
    return result;
}

public void printPascal(boolean upsideDown) {
    if (n == 0) { return; }
    for (int j = 0; j <= n; j++) {
        for (int i = 0; i < j; i++) {
            System.out.print(binom(j - 1, i).toString() + (j == i + 1 ? "\n" : " "));
        }
    }
}

【讨论】:

  • 我有一个递归方法,也包含 long binom,效果很好。我真的需要坚持我的原始代码。感谢您的帮助。
  • 如果你想使用 binoms,只需从 longs 切换到 BigIntegers。请记住,您可以更有效地计算 binom。我的意思是,你不应该执行任何除法。而不是计算n!/(k!(n-k)!,而是计算n*(n-1)*...*(k+1)/(n-k)!。还是比你的代码好。
【解决方案2】:

问题可能出在您对阶乘的计算中:我假设您的 int 类型最多可以容纳 32 位的数字,但可以容纳 13 位!比那个大。

您可以检查 long 是否可以存储更大的数字并将结果定义为 long。

【讨论】:

  • 当一个优秀的已被接受的答案已经存在时,在回答之前尽量确保你有新的信息(这个答案目前在低质量队列中)
  • 也许你应该在写作之前真正确定哪个答案是第一个
  • 你说得对,对不起,我没有注意到另一个答案也是最近的。新用户回答老问题很常见。
  • 好的。但是,您的评论既无帮助也不友好,因此毫无用处。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 2012-07-13
  • 1970-01-01
相关资源
最近更新 更多