Data structures 用于计算组合出现次数的数据结构

Data structures 用于计算组合出现次数的数据结构,data-structures,Data Structures,我有一堆符号,比如说{a,B,C,…},还有一个数据集。我需要计算每个组合出现的次数,例如{AB,AC,…,ABC,…,BC,}。符号的数量最多可达100个或更多。但许多组合都没有出现 第一个解决方案是我可以使用地图,但我认为它浪费了内存。我可以使用的第二个解决方案是trie,它共享前缀。第三种解决方案可以是一棵树,但每个符号都需要一棵树。我不知道它是否比trie好 那么你有什么建议吗?从评论中我想你是说你需要按大小的增加顺序列举子集。一种方法是简单的递归: #include <stdio

我有一堆符号,比如说
{a,B,C,…}
,还有一个数据集。我需要计算每个组合出现的次数,例如
{AB,AC,…,ABC,…,BC,}
。符号的数量最多可达100个或更多。但许多组合都没有出现

第一个解决方案是我可以使用
地图
,但我认为它浪费了内存。我可以使用的第二个解决方案是trie,它共享前缀。第三种解决方案可以是一棵树,但每个符号都需要一棵树。我不知道它是否比trie好

那么你有什么建议吗?

从评论中我想你是说你需要按大小的增加顺序列举子集。一种方法是简单的递归:

#include <stdio.h>
#include <string.h>

char set[] = "ABCD";
char buf[100];

void e(char *s, int len, int size, int p) {
  if (size == 0) {
    buf[p] = '\0';
    printf("{%s}\n", buf);
    return;
  }
  for (int i = 0; i <= len - size; ++i) {
    buf[p] = s[i];
    e(s + i + 1, len - i - 1, size - 1, p + 1);
  }
}

int main(void) {
  int len = strlen(set);
  for (int size = 0; size <= len; ++size) e(set, len, size, 0);
  return 0;
}

还有其他几种方法。如果您希望集合大小按其他顺序排列,此方法仍然是一个很好的起点。

如果集合是S,并且您有一个| S |位的二进制数,则它可以用于表示任何子集。1对应于集合中存在的元素。现在只需从0到2^N-1进行计数,并发出与每个值对应的集合。请注意,如果| S |=100或接近它的任何值,则需要30万亿年才能以每纳秒1的速度将它们全部列举出来。您是否在寻找组合或排列?对于置换,
AB
BA
被认为是不同的。对于组合,
AB
BA
被认为是同一件事。@这似乎是位图算法?它真正解决了问题的一部分,那就是找到子集。但它背后还有另一个问题:我需要单独计算每个子集,以便使频繁的组合先于不频繁的组合。你还有什么建议吗?@JimMischel这是组合,不是排列。元素的顺序被忽略。使用
map
是一种简单的方法,如果你有空闲的内存,这是非常合理的。我的建议是使用它,除非有什么原因你不能。如果它可以工作,并且在应用程序中工作得足够快,那么就使用它。只有在真正重要的时候才考虑优化内存或处理器周期。实际上这不是我想要的。问题中您忽略的关键点是存在一个数据集。这个问题是从另一个问题中提取出来的,它只是这个问题的一部分。我不是要列举每个组合,而是要计算数据集中组合的出现次数。
$ ./foo
{}
{A}
{B}
{C}
{D}
{AB}
{AC}
{AD}
{BC}
{BD}
{CD}
{ABC}
{ABD}
{ACD}
{BCD}
{ABCD}