Количество возможных комбинаций

В Java все переменные, которые вы объявляете, на самом деле являются «ссылками» на объекты (или примитивы), а не самими объектами.

При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.

Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».

Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки this. Возьмем этот пример:

public class Some {
    private int id;
    public int getId(){
        return this.id;
    }
    public setId( int newId ) {
        this.id = newId;
    }
}

И в другом месте вашего кода:

Some reference = new Some();    // Point to a new object of type Some()
Some otherReference = null;     // Initiallly this points to NULL

reference.setId( 1 );           // Execute setId method, now private var id is 1

System.out.println( reference.getId() ); // Prints 1 to the console

otherReference = reference      // Now they both point to the only object.

reference = null;               // "reference" now point to null.

// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );

// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...

Это важно знать - когда больше нет ссылок на объект (в пример выше, когда reference и otherReference оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.

5
задан Andres 12 September 2008 в 18:55
поделиться

7 ответов

@Torlack, @Jason Cohen: Рекурсия является плохой идеей здесь, потому что там "перекрывают подпроблемы". Т.е. Если Вы выбираете a как 1 и b как 2, затем у Вас есть 3 переменные, оставленные, который должен составить в целом 497; Вы прибываете в ту же подпроблему путем выбора a как 2 и b как 1. (Количество таких совпадений взрывается, когда числа растут.)

Традиционным способом приняться за решение такой проблемы является динамическое программирование: создайте таблицу вверх дном решений подпроблем (запускающийся с, "сколько комбинации 1 переменной составляют в целом 0?") затем растущий посредством повторения (решение, "сколько комбинаций n переменных составляет в целом k?" сумма решений к, "сколько комбинаций n-1 переменных составляет в целом j?" с 0 <= j <= k).

public static long getCombos( int n, int sum ) {
  // tab[i][j] is how many combinations of (i+1) vars add up to j
  long[][] tab = new long[n][sum+1];
  // # of combos of 1 var for any sum is 1
  for( int j=0; j < tab[0].length; ++j ) {
    tab[0][j] = 1;
  }
  for( int i=1; i < tab.length; ++i ) {
    for( int j=0; j < tab[i].length; ++j ) {
      // # combos of (i+1) vars adding up to j is the sum of the #
      // of combos of i vars adding up to k, for all 0 <= k <= j
      // (choosing i vars forces the choice of the (i+1)st).
      tab[i][j] = 0;
      for( int k=0; k <= j; ++k ) {
        tab[i][j] += tab[i-1][k];
      }
    }
  }
  return tab[n-1][sum];
}
$ time java Combos
2656615626

real    0m0.151s
user    0m0.120s
sys 0m0.012s
11
ответ дан 18 December 2019 в 07:58
поделиться

Ответ на Ваш вопрос равняется 2656615626.

Вот код, который генерирует ответ:

public static long getNumCombinations( int summands, int sum )
{
    if ( summands <= 1 )
        return 1;
    long combos = 0;
    for ( int a = 0 ; a <= sum ; a++ )
        combos += getNumCombinations( summands-1, sum-a );
    return combos;
}

В Вашем случае, summands 5 и sum 500.

Обратите внимание, что этот код является медленным. Если Вы нуждаетесь в скорости, кэшируете результаты summand,sum пары.

Я предполагаю, что Вы хотите числа >=0. Если Вы хотите >0, замените инициализацию цикла a = 1 и условие цикла с a < sum. Я также предполагаю, что Вы хотите перестановки (например. 1+2+3+4+5 плюс 2+1+3+4+5 и т.д.). Вы могли изменить для цикла, если бы Вы хотели a >= b >= c >= d >= e.

5
ответ дан 18 December 2019 в 07:58
поделиться

Я решил эту проблему для своего папы, которого пара несколько месяцев назад... расширяет для Вашего использования. Они имеют тенденцию быть проблемами времени, таким образом, я не пошел для самого допускающего повторное использование...

a+b+c+d = сумма

i = количество комбинаций

        for (a=0;a<=sum;a++)
        {
            for (b = 0; b <= (sum - a); b++)
            {
                for (c = 0; c <= (sum - a - b); c++)
                {
                    //d = sum - a - b - c;
                    i++
                }
            }
        }
2
ответ дан 18 December 2019 в 07:58
поделиться

Это на самом деле было бы хорошим вопросом спросить относительно интервью, поскольку это достаточно просто, который Вы могли описать на белой доске, но достаточно комплекс, что это могло бы сбить кого-то с толку, если они не думают достаточно тщательно об этом. Кроме того, Вы можете также для двух различных ответов, которые заставляют реализацию очень отличаться.

Вопросы порядка
Если порядок имеет значение затем, что любое решение должно позволить, чтобы нуль появился для любой из переменных; таким образом самое прямое решение было бы следующие:

public class Combos {
    public static void main() {
        long counter = 0;

        for (int a = 0; a <= 500; a++) {
            for (int b = 0; b <= (500 - a); b++) {
                for (int c = 0; c <= (500 - a - b); c++) {
                    for (int d = 0; d <= (500 - a - b - c); d++) {
                        counter++;
                    }
                }
            }
        }
        System.out.println(counter);
    }
}

Который возвращается 2656615626.

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

public class Combos {
    public static void main() {
        long counter = 0;

        for (int a = 1; a <= 500; a++) {
            for (int b = (a != 500) ? 1 : 0; b <= (500 - a); b++) {
                for (int c = (a + b != 500) ? 1 : 0; c <= (500 - a - b); c++) {
                    for (int d = (a + b + c != 500) ? 1 : 0; d <= (500 - a - b - c); d++) {
                        counter++;
                    }
                }
            }
        }
        System.out.println(counter);
    }
}

Который возвращается 2573155876.

2
ответ дан 18 December 2019 в 07:58
поделиться

Один способ посмотреть на проблему следующие:

Во-первых, банка быть любым значением от 0 до 500. Затем, если следует за этим b+c+d+e = 500-a. Это уменьшает проблему одной переменной. Рекурсивно вызовите, пока не сделано.

Например, если 500, то b+c+d+e=0, что означает, что для случая = 500, существует только одна комбинация значений для b, c, d и e.

Если 300, то b+c+d+e=200, который является на самом деле той же проблемой как исходная проблема, просто уменьшенная одной переменной.

Примечание: Как Chris указывает, это - ужасный способ фактической попытки решить проблему.

текст ссылки

1
ответ дан 18 December 2019 в 07:58
поделиться

Если они - вещественные числа, затем бесконечные... иначе это немного более хитро.

(Хорошо, для любого компьютерного представления вещественного числа было бы конечное количество..., но это будет большим!)

0
ответ дан 18 December 2019 в 07:58
поделиться

Включая отрицательные стороны? Бог.

Только включая положительные стороны? В этом случае их не назвали бы "целыми числами", но "naturals", вместо этого. В этом случае... Я не могу действительно решить это, мне жаль, что я не мог, но моя математика слишком ржава. Существует, вероятно, некоторый сумасшедший интегральный способ решить это. Я могу дать некоторые подсказки для математики, квалифицированной вокруг.

будучи x конечным результатом, диапазоном быть от 0 до x, диапазон b был бы от 0 до (x - a), диапазон c будет от 0 до (x - b), и т.д до e.

Ответ является суммой всех тех возможностей.

Я пытаюсь найти некоторую более прямую формулу на Google, но я являюсь действительно низким на своем Google-Fu сегодня...

-1
ответ дан 18 December 2019 в 07:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: