Перечислите все возможные комбинации - PullRequest
0 голосов
/ 27 января 2011

Вот что я пытаюсь сделать:

Учитывая список имен, распечатайте все комбинации имен, взятые по три за раз.Если в списке слишком мало элементов, ничего не печатайте.Имена должны появляться в том же порядке, в котором они появляются в списке.Итак, если список содержит имена Кеннеди, Джонсона, Никсона, Форда, вы запрограммируете отпечатки:

[Кеннеди, Джонсон, Никсон]
[Кеннеди, Джонсон, Форд]
[Кеннеди, Никсон, Ford] [Джонсон, Никсон, Ford]

Поместите значения в массив, а затем используйте метод Arrays.toString () для печати результатов, по одному в строке.

Параметры: список- - список имен.

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

Вот мой код:

int x = 0;
 int y = 1; 
 int z = 2; 


 for(int i = 0; i<list.length;i++){

  for (int j = 0;j<3;j++){

   System.out.print(list[x]);
   System.out.print(list[y]);
   System.out.print(list[z]);

   if (j>=1){y++;}
   if (z != list.length){z++;}

  }
  x++; 

 }

Вот ошибка, которую я получаю:

Enter commands:
trio Kennedy, Johnson, Nixon,ford
Kennedyjava.lang.ArrayIndexOutOfBoundsException: 1
 at MyAssign1.trio(MyAssign1.java:204)
 at Assign1.processOneCommand(Assign1.java:109)
 at CmdInterpreter.processCommands(CmdInterpreter.java:198)
 at CmdInterpreter.processCommands(CmdInterpreter.java:230)
 at CmdInterpreter.ooMain(CmdInterpreter.java:243)
 at MyAssign1.main(MyAssign1.java:20)

Строка 204:

System.out.print(list[y]);

Что яделать неправильно?

Ответы [ 6 ]

5 голосов
/ 27 января 2011

Как видно из комментариев к вашему вопросу, исключение ArrayIndexOutOfBoundsException происходит, потому что вы получаете доступ к индексу за пределами массива list. Взгляните:

if (j>=1){y++;}

Значение y всегда увеличивается. После list.length итераций исключение обязательно сработает. Решение для исключения простое: не обращаться к массиву с индексом за его пределами.

Несмотря на то, что существует множество решений проблемы комбинаций, наиболее простой способ вернуть вас на правильный путь:

for (int a = 0; a < list.length; a++) {
    for (int b = a + 1; b < list.length; b++) {
        for (int c = b + 1; c < list.length; c++) {
            System.out.print(list[a] + ", ");
            System.out.print(list[b] + ", ");
            System.out.println(list[c]);
        }
    }
}
3 голосов
/ 27 января 2011

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

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

Чтобы ответить на ваш реальный вопрос, в настоящее время вы получаете исключение, потому что вы получаете доступ к элементам после концасписок.Отчасти это связано с тем, что приращение до z равно list.length останавливается слишком поздно;массив длиной 4 содержит элементы с индексами 0-3, поэтому list[4] сгенерирует исключение, с которым вы сталкиваетесь.

(Прямо сейчас ваша логика поиска комбинации не будет работать правильно. x никогда не изменяется, поэтому каждая комбинация (с учетом примера) будет начинаться с Kennedy. Когда z достигает длины списка, она перестает расти, но y продолжает расти, поэтому вы получите несколько итераций, гдевторая и третья записи идентичны, и вы не рассмотрели, превысит ли y границы. Вы также перебираете i, но ничего не делаете с ним. Ваша программа, если она не вылетает, выдастчто-то вроде этого:

Kennedy, Johnson, Nixon
Kennedy, Johnson, Ford
Kennedy, Nixon, Ford
Kennedy, Ford, Ford
Kennedy, Johnson, Nixon
Kennedy, Johnson, Ford
Kennedy, Nixon, Ford
Kennedy, Ford, Ford
Kennedy, Johnson, Nixon
Kennedy, Johnson, Ford
Kennedy, Nixon, Ford
Kennedy, Ford, Ford
Kennedy, Johnson, Nixon
Kennedy, Johnson, Ford
Kennedy, Nixon, Ford
Kennedy, Ford, Ford

И у вас есть лот специального кожуха. Предположение, что вам нужно выполнить итерацию, в то время как j < 3 работает только тогда, когда ровно четыре элементаво входных данных. Проверка того, что вы должны увеличить y if j >= 1, снова является особым случаем, который создает правильный результат только с четырьмя элементами. Опять же, я призываю вас подуматьо процессе, который вы могли бы использовать, чтобы найти каждую перестановку из трех элементов на входе произвольной длины , вообще не думая о коде.)

0 голосов
/ 18 января 2014

Метод ниже принимает любое количество строк в качестве входного списка. И будет сгенерировано возможное количество перестановок / комбинаций. В случае перестановок вы также можете указать, нужна ли вам повторная строка или нет. обратите внимание, что если ComboOnly имеет значение true, то isRepeat не действует.

private static void generatePerms(List<String> list, boolean isRepeat, boolean comboOnly) {     
    int n = list.size();
    List<List<Integer>> lists = new ArrayList<List<Integer>>();

     for (int i = 0; i< n;i++) {
         int j = (comboOnly?i+1:0);
         for ( ; j < n;j++) {
             if (!isRepeat && i == j) continue;
             int k = (comboOnly?j+1:0);
             for (; k< n ;k++) {
                 if ( !isRepeat && (k ==i || k ==j)) continue;
                 System.out.println(list.get(i),list.get(j),list.get(k)));
             }
         }
     }

    return lists;
}
0 голосов
/ 27 января 2011

Попробуйте сравнить с моим решением, с менее сложной логикой:

import java.util.ArrayList;
import java.util.Arrays;

public class PrintCombinations
{
    private final static int LEN = 3;

    //for example: args = [Kennedy, Johnson, Nixon, Ford]
    public static void main(String[] args)
    {
        if (args.length < LEN)
            return; //too few data

        //collect combinations
        String[][] combinations = collectCombinations(args);

        //print result, one per line
        for(String[] comb : combinations)
        {
            System.out.println(Arrays.toString(comb));
        }
    }

    //collects all combinations and returns the result array 
    private static String[][] collectCombinations(String[] list)
    {
        int n = list.length;

        java.util.ArrayList<String[]> combinations = new ArrayList<String[]>();

        //the last possible 'i' is list[n-LEN], so no need go further
        for(int i = 0; i <= n - LEN; ++i)
        {
            //the last possible 'j' is list[n-(LEN-1)]
            for(int j = i+1; j <= n - (LEN-1); ++j)
            {
                //the last possible 'k' is list[n-(LEN-2)]
                //n-(LEN-2)==n-(3-2)==n-1, its the last element in the list
                for(int k = j+1; k <= n - (LEN-2); ++k)
                {
                    combinations.add(new String[] {
                            list[i],
                            list[j],
                            list[k]});  
                }               
            }
        }
        return combinations.toArray(new String[0][]);
    }
}

Я включил некоторую оптимизацию диапазона, чтобы избежать ненужных циклов внутри циклов. Вы не можете просто изменить LEN, чтобы изменить длину последовательности, это только для удаления «магического числа» 3 из кода.

Примечание: Если вы хотите более длинные последовательности вместо 3, вам нужно вставить новую глубину петли.

Надеюсь, это поможет!

0 голосов
/ 27 января 2011

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

Попробуйте добавить что-то подобное в ваш код, чтобы проверить это:

// Check size of list array.
System.out.println("list.length=" + list.length);

// Print out contents of list array.
for(int i=0; i<list.length; i++) {
   System.out.println(i + "=" + list[i]);
}
0 голосов
/ 27 января 2011

Я предполагаю, что вы используете это для переноса кода: http://www.cs.colostate.edu/~cs161/assignments/PA1/src/CmdInterpreter.java

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

trio Kennedy,Johnson,Nixon,Ford

Выход из пробелов может помочь синтаксическому анализатору интерпретировать массив.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...