Решение пройти максимальное значение целого числа?

Здравствуйте уважаемое сообщество,

Я думал об этом уже довольно давно, но, похоже, не могу найти решения.

У меня есть int[][] bino = new int[15][], в котором я вычисляю первые 15 строк пирамиды паскалей, и мне не разрешено менять тип (без двойных, длинных и т. д.).

Мы знаем, что на факультете из 12 человек 479001600 человек.

Максимальное значение int - 2147483647, поэтому fac (12) все еще подходит.

Теперь с последними 3 строками все усложняется.

Fac (13) - 6227020800, что слишком велико для int.

Итак, что происходит, так это то, что для строк 13, 14 и 15 не отображаются правильные числа (потому что 6227020800 mod 2147483647 = 1932053506, что означает, что fac (13) = 1932053506 в моем примере).

Вопрос в том, есть ли способ как-то еще отображать правильные числа, не меняя тип поля в int[][] bino = new int[15][]). Все остальное можно изменить.

public static void main(String args[])
{

    int[][] bino = new int[15][]; //Create 2d array for pascal pyramid
    for(int i = 0; i < bino.length;i++)
      for(int j = 0; j < bino[i].length;j++)
        {
           binos[i][j] = nOverk(i,j)
        }

}

public int nOverk(int n, int k)
{
   return(fac(n) / (fac(k) * fac((n-k))));
}
public int fac(int z) //Calculats the faculty of a number
{
   int res = 1;

   if (z == 0 || z == 1)
      return 1;

   for(int i = 2; i <= z; i++)
      res *= i;
   return res;
}

в long можно хранить большие значения, чем в int, или BigInteger. Я обнаружил, что рекомендуется использовать тип данных long, если возможно, если нет, то biginteger - см. stackoverflow.com/a/17416986/4892907

xxxvodnikxxx 09.01.2019 13:44
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
1
239
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Простое решение - использовать long, однако вы можете использовать int для больших чисел (и сэкономить работу), вместо этого вычислив fac(a)/fac(b), что более эффективно.

public static void main(String... args) {
    int[][] bino = new int[15][]; //Create 2d array for pascal pyramid
    for (int i = 0; i < bino.length; i++) {
        bino[i] = new int[i + 1];
        for (int j = 0; j < i + 1; j++) {
            bino[i][j] = nOverk(i, j);
        }
    }
}

static int nOverk(int n, int k) {
    int min = Math.min(k, n - k);
    int max = Math.max(k, n - k);
    return fac(n, max) / fac(min, 1);
}

static int fac(int hi, int lo) {
    if (hi == 0 || hi == 1)
        return 1;

    int res = 1;
    for (int i = lo + 1; i <= hi; i++)
        res *= i;
    return res;
}

AFAICT вы используете только соотв. нужен fac() для nOverk(). В термине fac(n) / (fac(k) * fac((n-k)))) вы можете исключить некоторые факторы, сохранив временные значения в допустимом диапазоне.

Например, вместо nOverk(4,2) = 4*3*2*1 / ((2*1) * (2 * 1)) вы просто вычисляете (4 * 3) / (2 * 1). Могут быть крайние случаи, когда это не помогает, но я думаю, что задача определена таким образом, и это помогает.

public int nOverk(int n, int k)
{
    return (lim_fac(n, k) / lim_fac(k, k));
}

private int lim_fac(int z, int n) //Calculats the "limited" faculty of a number, by multiplying n factors.
{
   int res = 1;

   if (n == 0) {
      return 1;
   }

   if (n == 1) {
      return z;
   }

   for (int i = z - n + 1; i <= z; i++) {
      res *= i;
   }

   return res;
}

Примечание: я не уверен на 100%, правильно ли я понял lim_fac(), но вы должны уловить идею.

В треугольнике Паскаля каждое число представляет собой сумму двух чисел прямо над ним. Если задача состоит только в том, чтобы напечатать первые 15 строк, вам действительно не нужно использовать факториал.

public static void main(String[] args) { 
    int n = 15;
    int[][] pascal  = new int[n+1][];

    // initialize first row
    pascal[1] = new int[1+2];
    pascal[1][1] = 1;

    // fill in Pascal's triangle
    for (int i = 2; i <= n; i++) {
        pascal[i] = new int[i+2];
        for (int j = 1; j < pascal[i].length - 1; j++)
            pascal[i][j] = pascal[i-1][j-1] + pascal[i-1][j];
    }

    // print results
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j < pascal[i].length - 1; j++) {
            System.out.print(pascal[i][j] + " ");
        }
        System.out.println();
    }
} 

Это, вероятно, лучший ответ, и он должен быть принятым.

glglgl 10.01.2019 09:02

Другие вопросы по теме