Декартово произведение произвольного числа множеств
Знаете ли вы несколько удобных библиотек Java, которые позволяют создавать декартово произведение двух (или более) наборов?
Например: у меня есть три набора. Один с объектами класса Person, второй с объектами класса Gift и третий с объектами класса GiftExtension .
Я хочу сгенерировать один набор, содержащий все возможные тройки Person-Gift-GiftExtension .
Количество наборов может варьироваться, поэтому я не могу сделать это во вложенном цикле foreach. При некоторых условиях моему приложению необходимо создать произведение пары Person-Gift, иногда это тройное Person-Gift-GiftExtension, иногда могут быть даже наборы Person-Gift-GiftExtension-GiftSecondExtension-GiftThirdExtension и т.д.
Переведено автоматически
Ответ 1
Редактировать: Удалены предыдущие решения для двух наборов. Подробности смотрите в истории редактирования.
Вот способ сделать это рекурсивно для произвольного числа наборов:
publicstatic Set<Set<Object>> cartesianProduct(Set<?>... sets) { if (sets.length < 2) thrownewIllegalArgumentException( "Can't have a product of fewer than two sets (got " + sets.length + ")");
return _cartesianProduct(0, sets); }
privatestatic Set<Set<Object>> _cartesianProduct(int index, Set<?>... sets) { Set<Set<Object>> ret = newHashSet<Set<Object>>(); if (index == sets.length) { ret.add(newHashSet<Object>()); } else { for (Object obj : sets[index]) { for (Set<Object> set : _cartesianProduct(index+1, sets)) { set.add(obj); ret.add(set); } } } return ret; }
Обратите внимание, что невозможно сохранить какую-либо информацию об универсальном типе вместе с возвращаемыми наборами. Если бы вы заранее знали, из скольких наборов вы хотели получить произведение, вы могли бы определить универсальный кортеж для хранения такого количества элементов (например, Triple<A, B, C>), но в Java нет способа иметь произвольное количество универсальных параметров.