我正在研究工作中的一些分组问题。有很多问题,请耐心等待。我发现它们非常有趣。如果这里的任何人对组合学也感兴趣,请帮助我。
好的,所以我们有一堆人物,这里我已经拍了一张。
我们可以将元素分组的方式是什么?让我们说我们有4个字符。 有效组(保留订单)将是:
a i d s
a i ds
id s
ai d s
ai ds
ids
援助
艾滋病
您如何列举所有群组?你能告诉我任何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”还有两个距离。是否有一个“中点”单词,您可以在距离最近的枚举中找到任何其他单词?从一个单词到另一个单词有多少条路径?
答案 0 :(得分:18)
答案 1 :(得分:2)
正如其他答案已经说过的那样,第1点有2 ^(n-1)个可能性。关于一些特殊情况(第2点):
那么,在这种情况下你有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的成本再次执行,依此类推,直到获得一个或多个匹配。