是否有有效的算法将返回所有不同的组合?

时间:2011-07-06 17:15:30

标签: algorithm combinations

已编辑:我的意思是组合而不是PERMUTATIONS

有效算法是否会返回给定数组中的所有不同排列? [“A”,“B”,“C”,“D”,“E”,“F”,“G”,“H”,“I”,“J”,“K”,......] < / p>

例如:AB,AC,AD,..,DE,..,HI,..,ABC,ABD,...,DEF,..,CDEFG,...,ABCDEFGHIJK,.... < / p>

我找到了一些算法,但它们返回所有排列而不是不同的排列。 不同我的意思是:

  1. AB&amp; BA是相同的排列

  2. DEF&amp; FED&amp; EFD&amp; DFE是相同的排列,

5 个答案:

答案 0 :(得分:10)

我能想到的最好的是一种二元计数器:

 A B C
-------
 0 0 0 | Empty Set
 0 0 1 | C
 0 1 0 | B
 0 1 1 | BC
 1 0 0 | A
 1 0 1 | AC
 1 1 0 | AB
 1 1 1 | ABC

答案 1 :(得分:2)

  1. 正如评论所指出的那样,您希望枚举所有子集,而不是排列。

  2. 最简单的方法是使用二进制计数器。例如,假设你有n个元素,那么像这样的东西可以用在C:

  3. 代码:

    for(int i=0; i<(1<<n); ++i)  {
       //Bits of i represent subset, eg. element k is contained in subset if i&(1<<k) is set.
    }
    

    我希望这有助于回答你的问题

答案 2 :(得分:2)

任何给定的项目是否在组合中。想想每个项目的布尔标志,说明它是否在组合中。如果你浏览布尔标志的每个可能的值列表,那么你已经完成了每个组合。

布尔值列表也称为二进制整数。

如果你有物品A-K,你有11件物品。因此,请浏览所有可能的11位数字。在Java中:

for (int flags = 0; flags < (1 << 11); ++flags) {
    int x = indexOfSomeItemFromZeroToTen();
    boolean isInCombination = ((i >> x) & 1) == 1;
}

如果要跳过空组合,请从1开始,而不是0。

答案 3 :(得分:0)

这些不是排列。 ABC排列{ABC, ACB, BCA, BAC, CAB, CBA}。您有兴趣找到{{1>}的所有不同的子集(也称为 power set )。这很容易做到:每个元素都可以包含或排除。这是一个递归算法:

{A,B,C, ..., K, ...}

答案 4 :(得分:0)

这是我编写的一些Ruby代码,现在有一段时间遍历数组中的每个组合。

def _pbNextComb(comb,length) # :nodoc:
 i=comb.length-1
 begin
  valid=true
  for j in i...comb.length
   if j==i
    comb[j]+=1
   else
    comb[j]=comb[i]+(j-i)
   end
   if comb[j]>=length
    valid=false
    break
   end
  end
  return true if valid
  i-=1
 end while i>=0
 return false
end

#
# Iterates through the array and yields each
# combination of _num_ elements in the array
#
# Takes an array and the number of elemens
 # in each combination
def pbEachCombination(array,num) 
 return if array.length<num || num<=0
 if array.length==num
  yield array
  return
 elsif num==1
  for x in array
   yield [x]
  end
  return
 end
 currentComb=[]
 arr=[]
 for i in 0...num
  currentComb[i]=i
 end
 begin
  for i in 0...num
   arr[i]=array[currentComb[i]]
  end
  yield arr
 end while _pbNextComb(currentComb,array.length)
end