2015-07-17 7 views
1

Я пытаюсь написать операцию, которая может перечислять все комбинации набора из N элементов. Другими словами, N неизвестен и зависит от пользовательского ввода. При приеме N функция должна иметь возможность дать всю возможную комбинацию набора N элементов, со всеми элементами из множества U. Скажем, U = {A, B, C ... J}, 10 элементов в Всего. Еще один пример того, что мне нужно, функция enumerate (3) должна рассказать мне все возможные комбинации, такие как {A, B, C}, {A, D, J} и т. Д., Используя элементы, выбранные из U.Перечисление комбинации n-элементов набора Java/Groovy

Я попытался сделать это так, чтобы использовать для циклов (инициализация целого числа, так как размер U в этом случае равен 10, поэтому я могу использовать 123 для обозначения {A, B, C} ...). Но код плохо пахнет, и я хотел бы знать, как это можно сделать более элегантно с использованием рекурсивных вызовов.

Java/Groovy являются приемлемыми (потому что я тоже пытаюсь в них). Если бы кто-нибудь мог представить идеи, как это сделать с закрытием в Groovy, это будет еще более оценено.

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

Спасибо!

+0

Можете ли вы показать свою попытку кода? – MaxZoom

ответ

1

Я считаю, что у меня есть решение.

import java.util.HashSet; 
import java.util.Set; 

public class Generator<T> { 
    Set<T> source; 
    Set<Set<T>> combinations; 

    public Generator(Set<T> source) { 
     this.source = source; 
    } 

    public static void main(String[] args) { 
     final Set<String> source = new HashSet<>(); 
     for (char character = 'A'; character <= 'Z'; character++){ 
      source.add(String.valueOf(character)); 
     } 

     final Generator<String> stringGenerator = new Generator<>(source); 
     stringGenerator.generate(3); 
    } 

    public void generate(int size){ 
     if (size == 0){ 
      return; 
     } 
     Set<Set<T>> newCombinations = new HashSet<>(); 
     for (T element : source) { 
      if (combinations == null || combinations.isEmpty()){ 
       final HashSet<T> set = new HashSet<>(); 
       set.add(element); 
       newCombinations.add(set); 
      } else { 
       for (Set<T> combination : combinations) { 
        final HashSet<T> newCombination = new HashSet<>(combination); 
        if (newCombination.add(element)) { 
         newCombinations.add(newCombination); 
        } 
       } 
      } 
     } 
     combinations = newCombinations; 
     generate(size - 1); 
    } 
} 

Это было быстро загрязнен реализация, поэтому, вероятно, он пропускает некоторые случаи, но в целом демонстрирует идею, по крайней мере, один рабочий случае.

+0

Большое спасибо @Yurii работает очень хорошо. Я предлагаю, может быть, изменение генерации (int size) для генерации (int осталось) может лучше прояснить себя? – OrlandoL

+0

@OrlandoL уверен, мой код нуждается в рефакторинге. Я только что изложил эту идею. Кстати, не могли бы вы принять ответ, который я сделал? – Yurii

+0

Несомненно @Yurii. Ответ довольно общий и гибкий, гораздо больше, чем я ожидал. Очень признателен – OrlandoL