Печать всех возможных комбинаций nCr в Java - PullRequest
4 голосов
/ 02 октября 2011

Я пытаюсь распечатать все возможности nCr, которые являются комбинациями, когда порядок не имеет значения.Таким образом, 5C1 есть 5 возможностей: 1, 2, 3, 4, 5. 5C2 есть 10 возможностей: 1 2, 1 3, 1 4, 1 5, 2 3, 2 4, 2 5, 3 4, 3 5,4 5.

Я сделал функции, которые печатают то, что я хочу для r = 2, r = 3 и r = 4, и я вроде как вижу шаблон, но я не могу создать рабочий метод для переменнойr:

public void printCombinationsChoose2(int n, int k) //for when k = 2
{
    for (int a = 1; a < n; a++)
    {
        for (int b = a + 1; b <= n; b++)
        {
            System.out.println("" + a + " " + b);
        }
    }
}

public void printCombinationsChoose3(int n, int k) //for when k = 3
{
    for (int a = 1; a < n - 1; a++)
    {
        for (int b = a + 1; b < n; b++)
        {
            for (int c = b + 1; c <= n; c++)
            {
                System.out.println("" + a + " " + b + " " + c);
            }
        }
    }
}

public void printCombinationsChoose4(int n, int k) //for when k = 4
{
    for (int a = 1; a < n - 2; a++)
    {
        for (int b = a + 1; b < n - 1; b++)
        {
            for (int c = b + 1; c < n; c++)
            {
                for (int d = c + 1; d <= n; d++)
                {
                    System.out.println("" + a + " " + b + " " + c + " " + d);
                }
            }
        }
    }
}

public void printCombinations(int n, int k) //Doesn't work
{
    int[] nums = new int[k];
    for (int i = 1; i <= nums.length; i++)
        nums[i - 1] = i;

    int count = 1;

    while (count <= k)
    {
        for (int a = nums[k - count]; a <= n; a++)
        {
            nums[k - count] = a;

            for (int i = 0; i < nums.length; i++)
                System.out.print("" + nums[i] + " ");
            System.out.println();
        }
        count++;
    }
}

Так что я думаю, что расположение моего последнего метода правильное, но я просто не делаю правильные вещи, потому что когда я вызываю printCominbations(5, 2), он печатает

1 2 
1 3 
1 4 
1 5 
1 5 
2 5 
3 5 
4 5 
5 5 

когда это должно быть то, что я сказал ранее для 5C2.

Редактировать Последний пример был плохим.Это лучше, чтобы проиллюстрировать, что он делает неправильно: printCombinations(5, 3) дает это:

1 2 3 
1 2 4 
1 2 5 
1 2 5 
1 3 5 
1 4 5 
1 5 5 
1 5 5 
2 5 5 
3 5 5 
4 5 5 
5 5 5 

Как я могу получить это:

1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5

Ответы [ 5 ]

6 голосов
/ 03 октября 2011

Как насчет этого:

public class Test {

    public static void main(final String[] args) {
        print_nCr(7, 4);
    }

    public static final void print_nCr(final int n, final int r) {
        int[] res = new int[r];
        for (int i = 0; i < res.length; i++) {
            res[i] = i + 1;
        }
        boolean done = false;
        while (!done) {
            System.out.println(Arrays.toString(res));
            done = getNext(res, n, r);
        }
    }

    /////////

    public static final boolean getNext(final int[] num, final int n, final int r) {
        int target = r - 1;
        num[target]++;
        if (num[target] > ((n - (r - target)) + 1)) {
            // Carry the One
            while (num[target] > ((n - (r - target)))) {
                target--;
                if (target < 0) {
                    break;
                }
            }
            if (target < 0) {
                return true;
            }
            num[target]++;
            for (int i = target + 1; i < num.length; i++) {
                num[i] = num[i - 1] + 1;
            }
        }
        return false;
    }
}

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

4 голосов
/ 02 октября 2011

Первая точка, где ваш код отклоняется от ожидаемого, здесь:

...
1 2 5 
1 2 5    <-- first bad output
1 3 5
...

Итак, задайте себе три вещи:

  • Что должно было произойти в этой строке кода с заданным состоянием переменных?

  • Почему мой код не совсем такой?

  • Что нужно изменить, чтобы добиться этого?

Ответ для первой части такой:

  • Он должен был увеличитьОт 2 до 3 и должны были быть установлены следующие числа в 4, 5, ... аналогично инициализации nums.

Вторая и третья части снова ваши.

Кстати: когда вы вернетесь, потому что вам нужна дополнительная помощь, пожалуйста, подробно объясните, что вы уже сделали и очистите и сократитевопрос совсем немного.

1 голос
/ 27 февраля 2013

Я сделал это в C ++

#include <iostream>

using namespace std;
#define ARR_LIMIT 100
int arr[ARR_LIMIT];

void _ncr(int N,int R, int n,int r , int start )
{
    if(r>0)
    {
        for(int i = start ; i <= start + (n-r); i++)
        {
            arr[R-r] = i;
            _ncr(N,R,N-i, r-1, i+1 );
        }
    }
    else
    {
        for(int i=0;i<R;i++)
        {
            cout << arr[i] << " ";
            if(i==R-1)
                cout<<"\n";
        }
    }

}

void ncr(int n,int r)
{
    //Error checking of parameters
    bool error = false;
    if( n < 1)
    {
        error = true;
        cout<< "ERROR : n should be greater 0 \n";
    }
    if( r < 1)
    {
        error = true;
        cout<< "ERROR : r should be greater 0 \n";
    }
    if(r > n)
    {
        error = true;
        cout<< "ERROR : n should be greater than or equal to r \n";
    }
    // end of Error checking of parameters
    if(error)
        return;
    else
        _ncr(n,r,n,r,1);
}

int main()
{
    int n,r;
    cout << "Enter n : ";
    cin >> n;
    cout << "Enter r : ";
    cin >> r;
    ncr(n,r);
    return 0;
}
1 голос
/ 02 октября 2011

ОК ... Каково решение, когда мы знаем, что нам нужны петли, а не их число? RECURSION ... Вам нужно использовать рекурсивную реализацию. Имейте это в виду: В ЛЮБОЕ время вам нужны циклы, но количество вложенных циклов может быть известно только во время выполнения, исходя из конкретных параметров проблемы, вы должны использовать рекурсивные методы ... Я дам вам некоторое время, чтобы попробовать сам, я вернусь, чтобы дать вам окончательную реализацию ...

0 голосов
/ 02 октября 2011

Расположение функции printCombination() кажется неправильным.Цикл while будет повторяться два раза для count = 1 и count = 2.

Когда count = 1, изменятся только значения в nums[0][here], так как в этом случае k - count = 1.Следовательно,
1,2
1,3
1,4 и
1,5.

А когда count = 2, только значения в nums[here][1] изменятся, поскольку здесь k - count = 0.Отсюда
1,5
2,5
3,5
4,5 и
5,5

...