2011-01-27 4 views
0

Вот что я пытаюсь сделать:Список всех возможных комбинаций

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

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

Поместите значения в массиве, а затем использовать метод 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]); 

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

+1

Вы пытаетесь получить доступ к элементу массива, который не существует. Например, если ваш массив имеет 3 элемента (длина 3, индексы от 0 до 2 включительно), и вы пытаетесь получить доступ к элементу 4 (индекс 3), вы увидите это исключение. –

+0

Если это домашнее задание, отметьте его как таковой. –

+0

Что находится в 'list'? –

ответ

5

В качестве комментариев по вашему вопросу возникает исключение 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]); 
     } 
    } 
} 
+0

Спасибо. Вот где я пытался. –

0

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

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

trio Kennedy,Johnson,Nixon,Ford 

Оставив пробелы, возможно, синтаксический анализатор интерпретирует массив.

3

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

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

Чтобы ответить на ваш реальный вопрос, вы в настоящее время получаете исключение, потому что вы получаете доступ к элементам, находящимся за концом списка. Это объясняется тем, что приращение до 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 

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

+0

Несколько раз повторяются значения: «Кеннеди, Форд, Форд». – vz0

+0

Да! Успешно справился. – HoldOffHunger

0

Я думаю, что ваша проблема не в код, который вы опубликовали, но в коде, который вы нам не показывали. Как вы создаете и заполняете массив 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

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

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

Ниже метод принимает любое количество строк в качестве входного списка. И создаст возможное количество перестановок/комбинаций. В случае перестановок вы также можете указать, нужна ли вам повторная строка или нет. обратите внимание, если ComboOnly истинно, то 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; 
} 
Смежные вопросы