组合:将角色分组挑战

时间:2009-07-14 18:47:01

标签: algorithm string math computer-science combinatorics

我正在研究工作中的一些分组问题。有很多问题,请耐心等待。我发现它们非常有趣。如果这里的任何人对组合学也感兴趣,请帮助我。

好的,所以我们有一堆人物,这里我已经拍了一张。

  1. 我们可以将元素分组的方式是什么?让我们说我们有4个字符。 有效组(保留订单)将是:

    a i d s a i ds
    id s
    ai d s
    ai ds
    ids
    援助 艾滋病

  2. 您如何列举所有群组?你能告诉我任何n个字母有多少组合?

    2。特例

    • 如果案件有所不同,例如Ai sd和ai sd是两组?

    • 您需要多长时间枚举所有案例?找到4个字母和5个字母的时间区别是什么?

    • 如果将“空格”作为字符。在所有枚举之后,你会写出多少个字符?

    • 如果您根据距离定义从单词到另一个单词的转换。 说“ai ds”和“a i ds”有1个距离,因为你应该将字母“i”移动一步。 你能找到任何单词两边n个距离的单词吗?

    编辑:
    “艾滋病”是一个单词 “ids”“援助s”是与原始单词“aids”相距1个距离的两个单词 “id s”是与原始单词“aids”相距两个距离的单词 “a i d s”是一个距离单词三个距离的单词。

    这个问题似乎是金矿。

    奖励:两个单词之间的最小距离是多少。就像“艾滋病”一样,距离“ids”还有两个距离。是否有一个“中点”单词,您可以在距离最近的枚举中找到任何其他单词?从一个单词到另一个单词有多少条路径?

5 个答案:

答案 0 :(得分:18)

答案 1 :(得分:2)

正如其他答案已经说过的那样,第1点有2 ^(n-1)个可能性。关于一些特殊情况(第2点):

  • 如果案件有所不同,例如Ai sd和ai sd是两组?

那么,在这种情况下你有2 ^ n个不同的案例组合,所以你有2 ^ n * 2 ^(n-1)= 2 ^(2 * n - 1)种可能性。

  • 如果您将“空格”作为角色。在所有枚举之后,你会写出多少个字符?

这是一个更有趣的问题。你有1个可能没有空间,3个可能放置1个空间,3个可能放置2个空间,1个可能放置3个空间。如果我没记错的话,这是一个二项分布,并且有计算数字的公式。您也可以使用Pascal's triangle

   1
  1 1
 1 2 1
1 3 3 1 <- your case (4th row)
  ...

获得这些数字后,计算总字符数如下:

1*4 + 3*5 + 3*6 + 1*7 = 44 

答案 2 :(得分:1)

http://www-cs-faculty.stanford.edu/~knuth/fasc3b.ps.gz(如果您无法查看postscript,请下载Ghostscript / Ghostview)详细讨论分区。

对于长度为n的序列,有2 ^(n-1)个分区。想想每对连续项目之间的一点点。如果该位置位,则它们被分开(通过空格,如您所列出的那样)。 “艾滋病”(长度4)有2 ^ 3个可能的分区。

回复您的其他问题:

枚举时间:O(n * 2 ^ n) - 输出长度不变。项目数量不仅随着输入长度的增加而增加,而且每个项目中的字符数也会增加。

写入的字符数:不要计算换行符(如果这样做,则添加另外2 ^(n-1)个字符)。然后你有n * 2 ^(n-1)个非空格字符,加上所有唯一的n-1个数字位串中的1个数。当写出时,k位数字串具有k * 2 ^ k位,其中一半为1.所以字符总数为[n +(n-1)/ 2] * 2 ^(n-1) ),不包括换行符。在“艾滋病”的8个变体列表中,有32个非空格字符,12个空格 - 分别为4 * 2 ^ 3和(3/2)* 2 ^ 3。

编辑距离:您必须更准确地了解转换及其成本。通过“单词”我假设你的意思是一个单独的分区(你的8个示例行之一)。如果编辑是删除或添加单个空格,那么你在谈论n-1位数字串的汉明距离。

答案 3 :(得分:1)

用于访问距离k或更短距离内的每个单词的简单算法:使用哈希表仅访问每个位串(或2 ^(n-1)位的数组,但可能太大),递归地访问每个相邻的单编辑差异(假设汉明距离:对于i从1 ...(n-1),XOR 2 ^ i与源位串,切换第i位)。

这样做深度为k(深度与递归一起传递),并且您将访问距离k内的所有编辑。当然,如果你只想要那些具有深度k的那些,你将需要使用广度优先搜索:而不是立即访问每个邻居,将它们保存在队列中以便访问。在访问给定代(j)的项目(所有具有相同的最佳编辑距离)的队列时,将未来项目排队在下一代(j + 1)的不同队列中。这样,您首先使用尽可能少的编辑次数访问每个字符串(广度优先=当每次转换具有相同的成本时,最好是第一个。)

如果您不想进行广度优先搜索,那么您可以随时计算k或更小的单词集,以及k-1或更小的单词集,并采取差异(您将使用两个单独的表)。这实际上是“迭代加深搜索”。

B-K树不适合这里,除非你正在考虑一组非结构化的单词(一般字典)。我们已经确切地知道单个单词的分区结构。

答案 4 :(得分:0)

计数参数是正确的。

我通常使用分支绑定来编写这样的问题。 Here's an example.

基本上,您不是编写循环来扫描字符串,而是编写递归函数,并将成本跟踪作为其参数之一。然后在每一步,您可以1)降低字符串,额外成本为零,然后2)对字符串进行一些小的更改,向成本添加增量,然后前进,3)重复2你想要考虑多种不同的变化。

然后有一个总体成本预算,并且拒绝接受成本超出预算的任何分支。

最后,作为外部循环,在预算为0的情况下完成整个过程。如果不产生任何匹配,则以1的成本再次执行,依此类推,直到获得一个或多个匹配。