Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 为具有重复项的列表生成所有组合_Algorithm_Combinations - Fatal编程技术网

Algorithm 为具有重复项的列表生成所有组合

Algorithm 为具有重复项的列表生成所有组合,algorithm,combinations,Algorithm,Combinations,与之相关,我想知道为一个总共包含m元素的列表生成r元素的所有组合的算法(以及java/c/c++/python/等中的实际代码,如果有的话!)。其中一些m元素可能会重复 谢谢 针对每种元素类型递归 int recurseMe(list<list<item>> items, int r, list<item> container) { if (r == container.length) { //print out your collection

与之相关,我想知道为一个总共包含
m
元素的列表生成
r
元素的所有组合的算法(以及java/c/c++/python/等中的实际代码,如果有的话!)。其中一些
m
元素可能会重复


谢谢

针对每种元素类型递归

int recurseMe(list<list<item>> items, int r, list<item> container)
{
  if (r == container.length)
  {
    //print out your collection;
    return 1;
  }
  else if (container.length > score)
  {
    return 0;
  }
  list<item> firstType = items[0];
  int score = 0;
  for(int i = 0; i < firstType.length; i++)
  {
    score += recurseMe(items without items[0], r, container + i items from firstType);
  }
  return score;
}
int recurseMe(列表项、int r、列表容器)
{
if(r==container.length)
{
//打印出你的收藏;
返回1;
}
else if(container.length>score)
{
返回0;
}
list firstType=项目[0];
智力得分=0;
for(int i=0;i
这需要一个包含项目列表的列表作为输入,假设每个内部列表表示一种唯一的项目类型。您可能需要构建一个排序函数,以作为输入提供给此函数

//start with a list<item> original;
list<list<item>> grouped = new list<list<item>>();
list<item> sorted = original.sort();//use whichever method for this
list<item> temp = null;
item current = null;
for(int x = 0; x < original.length; x++)
  if (sorted[x] == current)
  {
    temp.add(current);
  }
  else
  {
    if (temp != null && temp.isNotEmpty)
      grouped.add(temp);
    temp = new list<item>();
    temp.add(sorted[x]);
  }
}
if (temp != null && temp.isNotEmpty)
  grouped.add(temp);
//grouped is the result
//从原始列表开始;
列表分组=新列表();
list sorted=original.sort()//使用哪种方法进行此操作
列表温度=空;
项目当前=空;
对于(int x=0;x

这将对列表进行排序,然后创建包含相同元素的子列表,将它们插入到列表的列表中
分组

我将给出一个答案,而不是一堆注释

我最初的评论是:


CombinationGeneratorJava类系统地生成所有 n个元素的组合,一次取r。算法是 Kenneth H.Rosen描述的离散数学及其应用 应用,第二版(纽约:麦格劳·希尔,1991),第284-286页。“见 merriampark.com/comb.htm。它有一个到源代码的链接

正如您在评论中指出的,您需要独特的组合。因此,给定数组
[“a”、“a”、“b”、“b”]
,您希望它生成
aab,abb
。我链接的代码生成
aab,aab,baa,baa

使用该数组,删除重复项非常容易。根据您的实现方式,您可以让它生成重复项,然后在事后对其进行过滤(即从数组中选择唯一的元素),或者修改代码以包含哈希表,以便在生成组合时,在将项放入输出数组之前检查哈希表

在哈希表中查找某个内容是一个
O(1)
操作,因此这两个操作中的任何一个都将是有效的。在事后执行此操作的成本会稍高一些,因为您必须复制项。不过,您所说的是
O(n)
,其中
n
是生成的组合数

有一个复杂问题:顺序是不相关的。也就是说,给定数组
[“a”、“b”、“a”、“b”]
,代码将生成
aba、abb、aab、bab
。在这种情况下,
aba
aab
是重复的组合,就像
abb
bab
一样,使用哈希表不会为您删除这些重复项。不过,您可以为每个组合创建位掩码,并使用哈希表的思想使用位掩码。这会稍微复杂一点,但不是非常复杂

如果您首先对初始数组进行排序,使重复项相邻,那么问题就会消失,您可以使用哈希表的思想

毫无疑问,有一种方法可以修改代码以防止其生成重复代码。我可以看到一种可能的方法,但它会很混乱且昂贵。这可能会使算法比仅使用哈希表的想法慢。我将采取的方法是:

Sort the input array
Use the linked code to generate the combinations
Use a hash table or some other code to select unique items.
虽然…我有一个想法


如果对输入数组进行排序,则生成的任何重复项都是相邻的,这是真的吗?也就是说,给定输入数组
[“a”、“a”、“b”、“b”]
,则生成的输出将按该顺序为
aab、aab、abb、abb
。当然,这将取决于实现。但如果在您的实现中是真的,那么修改算法以删除重复项只需检查当前组合是否与前一个相同。

这里是一个递归我相信这和Jean-Bernard Pellerin在Mathematica中的算法密切相关

这将输入作为每种类型元素的编号。输出形式类似。例如:

{a,a,b,b,c,d,d,d,d} -> {2,2,1,4}
功能:

f[k_, {}, c__] := If[+c == k, {{c}}, {}]

f[k_, {x_, r___}, c___] := Join @@ (f[k, {r}, c, #] & /@ 0~Range~Min[x, k - +c])
使用:

如果组合值(其长度)的总和等于
k
,则返回该组合,否则返回一个空集。(
+c
加[c]
的缩写)

否则:

f[k_, {x_, r___}, c___] := Join @@ (f[k, {r}, c, #] & /@ 0~Range~Min[x, k - +c])
从左到右阅读:

  • Join
    用于展平嵌套列表的级别,以便结果不是一个越来越深的张量

  • f[k,{r},c,#]&
    调用该函数,删除选择集的第一个位置(
    x
    ),并向组合中添加新元素(
    #

  • /@0~Range~Min[x,k-+c])
    用于选择集第一个元素的0和较小值之间的每个整数,并且
    k
    小于组合总数,这是在不超过组合大小的情况下可以选择的最大值
    k


@Jean Bernard:combination vs.permutation!”CombinationGenerator Java类系统地生成n个元素的所有组合,每次取r。该算法由Kenneth H.Rosen描述,《离散数学及其应用》,第二版(纽约:McGraw-Hill,1991),第284-286页。“参见。它有一个到源代码的链接。@JimMischel:这不是我想要的。对于字符串[]el {{0, 0, 0, 4}, {0, 0, 1, 3}, {0, 1, 0, 3}, {0, 1, 1, 2}, {0, 2, 0, 2}, {0, 2, 1, 1}, {1, 0, 0, 3}, {1, 0, 1, 2}, {1, 1, 0, 2}, {1, 1, 1, 1}, {1, 2, 0, 1}, {1, 2, 1, 0}, {2, 0, 0, 2}, {2, 0, 1, 1}, {2, 1, 0, 1}, {2, 1, 1, 0}, {2, 2, 0, 0}}
f[k_, {}, c__] := If[+c == k, {{c}}, {}]
f[k_, {x_, r___}, c___] := Join @@ (f[k, {r}, c, #] & /@ 0~Range~Min[x, k - +c])