我正在寻找一种解决特定类型拼图的算法。给定输入字符串和隐藏短语单词的字符计数列表,我想找到隐藏在其中的可能短语列表。组成短语的字符在字符串中按顺序出现,但有时在其间插入随机的额外字符。一个例子:
拼图字符串:
typacnmlllrspoanrjaoadiisrleeairebsdrqletsaormelomtuapkeerfsrhlwcoipmaycarwacyhrsolneoaieeeteibtuillllndepwctstravelebotseibubblensooysadosnickershwdctgmixturesasonogidropsyggnlpaugoumugpawelaecgbarrynitkymmezhmtsffoljmsnsxbw
隐藏短语字符数:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
此输入的正确隐藏短语是:
all roads lead to rome was not built in a day
可能会有多个匹配的短语;然后,我可以缩小搜索空间,并使用辅助算法或手动进一步细化结果。
答案 0 :(得分:0)
我认为解决这个问题的方法是找到第一个单词,你可以找到每个单词必需数量的字母(通过第一个单词,我的意思是最早结束)。例如,您想要的第一个单词是三个字母 - 在TYPACMLL
中,您可以找到前三个字母单词PAL
。我们知道,如果存在解决方案,则必须存在以PAL
开头的解决方案。这是因为,如果存在另一个解决方案(例如以ALL ROADS LEAD
开头的解决方案)并且稍后结束的单词,那么我们可以简单地使用该解决方案并将其应用于PAL
:{ {1}}。
所以现在你只需要设计一个算法来查找字符串中第一个长度为PAL ROADS LEAD
的单词。这可以n
以非常强力的方式完成:
O(N^2 * C)
这无疑具有一个很大的常数因子for l in string:
for word in dictionary that has k letters and starts with l:
if word exists in string:
store word
store end_pos
,字典中以字母l开头的长度为k个字的数量,但至少不依赖于字符串的长度。当然你可以在这里进行一些优化,比如你的字符串末尾的字符修剪,因为你知道必须至少有足够的字符来匹配你秘密模式的其余部分,或者有一些早期终止和猜测的启发式 - 重复如果有必要的话。
下一步是重复此过程,使用从刚刚找到的单词末尾处的字母开始的子字符串以及最小的end_pos。因此,算法的总运行时间为C
,因为您必须最多使用该算法O(N^3)
次。
希望这是你想要的 - 我可能误解了这个问题。
注意强>
这种算法称为 greedy 算法,该算法利用交换原理:贪婪算法给出的结果并不比任何时间点的最优解都差。有关此内容的更多信息(交换参数),您可以看到:this paper第4.2节