Неправильный вывод треугольника Паскаля
Привет, я делаю итеративный треугольник Паскаля в Java. Пока все отлично работает, пока количество строк не превысит 13. Вывод становится неисправным. Должно быть, я что-то делаю не так, пожалуйста, помогите.
IterativePascal:
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
Помощь будет оценена, так как я новичок в алгоритмах.
2 ответа
Вы достигаете переполнения номера. Так как 14!
слишком большой, чтобы заполнить Java long
,
Решение будет использовать +
вместо !
,
Сохраняйте свой треугольник как двумерный массив и повторяйте его. Каждая ячейка должна быть суммой двух "выше".
+---+---+---+---+
| 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 требует рекурсивного решения с биномами, я решил добавить решение, представляющее BigInteger
Как бы то ни было.
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" : " "));
}
}
}
Возможно, проблема в том, что вы вычисляете факториал: я предполагаю, что ваш тип int может содержать числа до 32 бит, но 13! больше, чем это.
Вы можете проверить, может ли long хранить большие числа, и определить результат как long.