因此,我試圖從給定的N元素集合中找到所有k元素子集的問題。我知道使用公式C(n,k)= C(n-1,k-1)+ C(n-1,k)的k個子集的總數是多少,我也知道如何去做以迭代的方式,但是當我嘗試去思考遞歸解決方案時,我陷入了困境。任何人都可以給我一個提示嗎? 謝謝!如何在Java中遞歸地生成N元素集合中的所有k元素子集
回答
對於集合中的每個元素,取該元素,然後依次添加剩餘N-1個元素集合的所有(k-1)個子集。
「這是個月黑風高的夜晚,船長說......」
提及安東尼奧。 – 2010-11-04 15:40:32
我真的需要一個關於如何將它轉換爲遞歸方法的想法,因爲如前所述,我有一個涉及嵌套循環的迭代解決方案,但不知道如何將其轉換爲遞歸方法。 – rdplt 2010-11-04 16:18:49
這是一個遞歸的方法!它說產生一個N集合的k子集的問題與取N的每個元素相同,然後計算剩下的N-1個大小的集合的k-1集合。當K變爲1時,計算出它的子集是微不足道的。 – 2010-11-04 16:24:50
更好
這打破了k=0
情況下,因爲我認爲它會返回一個包含了一組空集,這是不正確的。無論如何。這裏還有一個迭代,如果目標是遞歸的,你可以用遞歸替換它。這是對wikipedia: powerset給出的算法的相當直接的修改。我會留下修復角落案件(k = 0)給讀者。
這不是正確的尾遞歸,並不是它在大多數JVM中都很重要。 (我猜的IBM JVM做到這一點...)
class RecursivePowerKSet
{
static public <E> Set<Set<E>> computeKPowerSet(final Set<E> source, final int k)
{
if (k==0 || source.size() < k) {
Set<Set<E>> set = new HashSet<Set<E>>();
set.add(Collections.EMPTY_SET);
return set;
}
if (source.size() == k) {
Set<Set<E>> set = new HashSet<Set<E>>();
set.add(source);
return set;
}
Set<Set<E>> toReturn = new HashSet<Set<E>>();
// distinguish an element
for(E element : source) {
// compute source - element
Set<E> relativeComplement = new HashSet<E>(source);
relativeComplement.remove(element);
// add the powerset of the complement
Set<Set<E>> completementPowerSet = computeKPowerSet(relativeComplement,k-1);
toReturn.addAll(withElement(completementPowerSet,element));
}
return toReturn;
}
/** Given a set of sets S_i and element k, return the set of sets {S_i U {k}} */
static private <E> Set<Set<E>> withElement(final Set<Set<E>> source, E element)
{
Set<Set<E>> toReturn = new HashSet<Set<E>>();
for (Set<E> setElement : source) {
Set<E> withElementSet = new HashSet<E>(setElement);
withElementSet.add(element);
toReturn.add(withElementSet);
}
return toReturn;
}
public static void main(String[] args)
{
Set<String> source = new HashSet<String>();
source.add("one");
source.add("two");
source.add("three");
source.add("four");
source.add("five");
Set<Set<String>> powerset = computeKPowerSet(source,3);
for (Set<String> set : powerset) {
for (String item : set) {
System.out.print(item+" ");
}
System.out.println();
}
}
}
發電機組只有 這並不可能完全得到那裏,是不是真的優雅,但它遞歸計算全冪,然後修剪它(迭代)的大小。
class RecursivePowerSet
{
static public <E> Set<Set<E>> computeConstrainedSets(final Set<Set<E>> source, final SizeConstraint<Set<E>> constraint)
{
Set<Set<E>> constrained = new HashSet<Set<E>>();
for (Set<E> candidate : source) {
if (constraint.meetsConstraint(candidate)) {
constrained.add(candidate);
}
}
return constrained;
}
static public <E> Set<Set<E>> computePowerSet(final Set<E> source)
{
if (source.isEmpty()) {
Set<Set<E>> setOfEmptySet = new HashSet<Set<E>>();
setOfEmptySet.add(Collections.EMPTY_SET);
return setOfEmptySet;
}
Set<Set<E>> toReturn = new HashSet<Set<E>>();
// distinguish an element
E element = source.iterator().next();
// compute source - element
Set<E> relativeComplement = new HashSet<E>(source);
relativeComplement.remove(element);
// add the powerset of the complement
Set<Set<E>> completementPowerSet = computePowerSet(relativeComplement);
toReturn.addAll(completementPowerSet);
toReturn.addAll(withElement(completementPowerSet,element));
return toReturn;
}
static private <E> Set<Set<E>> withElement(final Set<Set<E>> source, E element)
{
Set<Set<E>> toReturn = new HashSet<Set<E>>();
for (Set<E> setElement : source) {
Set<E> withElementSet = new HashSet<E>(setElement);
withElementSet.add(element);
toReturn.add(withElementSet);
}
return toReturn;
}
public static void main(String[] args)
{
Set<String> source = new HashSet<String>();
source.add("one");
source.add("two");
source.add("three");
source.add("four");
source.add("five");
SizeConstraint<Set<String>> constraint = new SizeConstraint<Set<String>>(3);
Set<Set<String>> powerset = computePowerSet(source);
Set<Set<String>> constrained = computeConstrainedSets(powerset, constraint);
for (Set<String> set : constrained) {
for (String item : set) {
System.out.print(item+" ");
}
System.out.println();
}
}
static class SizeConstraint<V extends Set> {
final int size;
public SizeConstraint(final int size)
{
this.size = size;
}
public boolean meetsConstraint(V set)
{
return set.size() == size;
}
}
}
這是一些僞代碼。通過隨時隨地存儲每個呼叫的值,並在遞歸呼叫檢查之前(如果呼叫值已存在),可以剪切相同的遞歸調用。
以下算法將具有排除空集的所有子集。
list * subsets(string s, list * v){
if(s.length() == 1){
list.add(s);
return v;
}
else
{
list * temp = subsets(s[1 to length-1], v);
int length = temp->size();
for(int i=0;i<length;i++){
temp.add(s[0]+temp[i]);
}
list.add(s[0]);
return temp;
}
}
- 1. 在Python中生成大小爲k(包含k個元素)的所有子集
- 2. 生成功率集的所有元素
- 3. 如何生成數組中所有n個元素的組合?
- 4. 將N個元素分成k個大小的子集
- 5. 如何遞歸選擇父元素下的所有子元素?
- 6. 集合/數論:在n個集合的k個子集中,特定元素的出現次數爲
- 7. 從集合中取出n個元素
- 8. 從集合中刪除N元素
- 9. 如何找到一組所有可能的n元素子集?
- 10. 生成k個最獨特的子集對元素
- 11. 如何定義Coq中N個元素的有限集合?
- 12. 如何獲得使用Java的元素集合的子集?
- 13. java獨特元素集合
- 14. 子集和組合元素
- 15. 所有XML元素的查詢集合
- 16. Java:刪除集合中的元素
- 17. 集合中元素的子字符串
- 18. 在MPI中按元素明智地收集和收集元素
- 19. 生成n元素集的子集;函數不返回任何東西
- 20. 如何將一個元素及其所有元素放入一個集合中?
- 21. 獲得集合的第n個元素
- 22. 如何從k個項目列表中生成所有n大小的集合?
- 23. 如何在lxml中遞歸地獲取特定元素和子元素?
- 24. 找到n個元素的所有可能的分區與k大小的子集,其中兩個元素只共享相同的集合一次
- 25. 生成元素的所有組合
- 26. 生成{0,1,2,... n-1}的所有大小k子集
- 27. 在Angular js中顯示或生成集合元素到表中
- 28. 如何有效地追蹤集合中最小的元素?
- 29. k個元素的全部組合n
- 30. MongoDB幫助獲取集合中的所有元素A不在集合中B
是否所有N元素都不同? – 2010-11-04 15:27:32
您應該閱讀格雷碼。 – 2010-11-04 15:31:33
@SKD,我假設是這樣,它是一組 – 2010-11-04 15:31:44