解决有序列表中的模糊类别

时间:2009-03-04 20:39:15

标签: algorithm math function

让我们举一个具体的例子,希望我能清楚。假设(有序)月份列表:

  

1月<二月<三月< ......<   腊

(整数代表月份,从零开始),这样

  

Jan是0,2月是1,...,Dec是11。

现在假设我无法访问月份的全名,并且给出了以下列表,其中几个月缩短为第一个字母, e 代表空类别,如这样:

  

e,F,e,e,e

如果我建立一个“明确的月份”列表(f:1,s:8,o:9,n:10,d:11),我可以通过先计算第一个类别来填充空类别(使用减法和mod 12),然后从那里写下其余部分。但是,假设我获得了列表

  

e,A,e,e,J,e

然后我可以(直观地)计算出虽然 A 不明确(可能是4月或8月),但在这种情况下它只能是4月,因为8月没有任何 J < / em>在2个类别之后跟随它。一旦我找到了这个,我可以从一开始就再次计算一切。

最后,我的问题是:是否存在针对此问题的分析解决方案(函数,算法),或者我唯一希望使用强力来定义每个潜在的关系?对于某些示例,没有消歧算法/函数可以工作:考虑我有 J 后跟11 e 的情况,然后是 J 其次是11 e ...由于介于两年之间,我无法将 J 的歧义消除到1月,6月或7月。

答案:我最终编写了Il-Bhima的答案,因为特别是对于这种情况,即使在较高的运行时间O(mn),正则表达式也没问题。但是,我接受了Ben的答案作为正确答案,因为它包含了其他答案(提到正则表达式解决方案),但也提出了一种更好的方法,使用KMP算法O(m + n),尽管这是针对更大数量的字符串反对匹配模式。谢谢,大家。

3 个答案:

答案 0 :(得分:5)

我不确定这是否正是您正在寻找的,但您可以使用修改后的KMP string search algorithm来解决此问题。

修改将匹配空类别的任何内容。它甚至可以为您找到所有可能的值,例如您提到的11 e的J。

你也可以使用finite state machine来确定可能性,这就是regular expression会做的事情。

答案 1 :(得分:4)

最简单的方法是使用正则表达式。假设您要匹配e, A, e, e, J, e

构造以下正则表达式:r = ".A..J."

c成为我们的控制字符串:

  c = "JFMAMJJASONDJFMAMJJASOND"

现在我们搜索字符串rc的所有匹配项,其中匹配的起始索引位于c的前半部分。

一般来说,这可能不是最有效的方法。尝试将模式与控制字符串"JFMAMJJASOND"的每个循环移位匹配的最天真的解决方案在O(nm)时间运行,其中n是模式的长度m是控制字符串的长度(在我们的例子中是JFMAMJJASOND)。

答案 2 :(得分:2)

我们可以根据一般情况对Il-Bhima的答案进行一些修改。首先,我们认识到A,M或J中唯一真正含糊不清的对是两个相隔六个月的J,或两个相隔一年的相同字母。任何其他组合将在控制字符串中产生明确的匹配。 (我建立了一个包含所有可能组合的表来证明这一点。)

所以你需要从你的整个起始列表中得到的是两个月的距离mod 12不是0或6.然后你可以建立一个小的正则表达式来匹配控制字符串。或者,您可以构建一个包含有序对的查找表以及月份之间的距离。