2015-10-25 3 views
0

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

Я разместил свой рабочий код ниже.

import java.util.*; 
public class AllSubsets { 
    public static void main(String[] args) { 
     // Change contents of this array to easily change contents of set. 
     Integer[] setContents = {3, 6, 8, 9, 10, 22}; 
     // create initial unused set by dumping all of the aray into a set. 
     Set<Integer> unused = new HashSet<Integer>(Arrays.asList(setContents)); 
     // create initial empty set for used set. 
     Set<Integer> used = new HashSet<Integer>(); 
     // create output set of sets. 
     Set<Set<Integer>> allSets = new HashSet<Set<Integer>>(); 
     allSets.add(used); 
     // find all sets recursively 
     findAllSets(used, unused, allSets); 
     // print out results 
     System.out.println(allSets); 
    } 

    public static void findAllSets(Set<Integer> used, Set<Integer> unused, 
            Set<Set<Integer>> allSets) { 
     if (unused != null) { 
     Set<Integer> copyOfUnused = new HashSet<Integer>(unused); 
     for (Integer val : copyOfUnused) { 
      unused.remove(val); 
      used.add(val); 
      allSets.add(new HashSet<Integer>(used)); 
      findAllSets(used, unused, allSets); 
      used.remove(val); 
      unused.add(val); 
     } 
     } 
    } 
} 

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

Set<Set<Integer>> allSets = 
    new TreeSet<Set<Integer>>(new Comparator<Set<Integer>>() { 
     public int compare(Set<Integer> a, Set<Integer> b) { 
      return a.size() - b.size(); 
     } 
    }); 

В этой версии кода, он компилирует, но объекты не правильно хранить. Соответствующие наборы вычисляются и добавляются к «allSets» в рекурсивном методе (проверяется с использованием println), но он всегда содержит только один набор за раз. У меня такое чувство, потому что я переписывал Comparator для Set, но я использую HashSets. Есть ли лучший способ организовать мои наборы или, может быть, небольшую ошибку в моем коде?

Спасибо!

+1

Вместо того, чтобы создавать Набор наборов в качестве вывода создает список наборов и записывает компаратор. – bhspencer

+1

Я не знаю, используете ли вы Java 8, но если вы, вы можете сделать 'Comparator.comparingInt (Set :: size)'. –

+0

@bhspencer Это означает, что мне нужно проверить вручную, существует ли элемент внутри списка, прежде чем добавлять его? Список не сохраняет свойство, что все элементы должны быть уникальными? Наборы делают это автоматически для меня, поэтому я использовал набор. – Chris

ответ

3

TreeSet<Set<Integer>> будет хранить только один элемент Set с заданным размером, потому что он считает, что два разных набора с одинаковым размером равны: требуется a.compareTo(b) == 0, что означает a == b.

Если вы хотите, чтобы получить все наборы, а затем распечатать их в порядке размера, собрать все наборы в обычном (Hash) Set, а затем отсортировать записи:

List<Set<Integer>> listOfSets = new ArrayList<>(allSets); 
Collections.sort(listOfSets, <your comparator above>); 
System.out.println(listOfSets). 
+0

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

Смежные вопросы