用字典解析字符串的算法

时间:2011-07-20 18:03:44

标签: c++ algorithm parsing dictionary

给出

  • 一个充满单词{in, july, den, dentist, best, ...}的词典,其中有一些C ++ API可以访问它:boolean findWord(string word)string getNextWord(void)来迭代它,

  • 一些没有空格的输入字符串,例如:bestdentistinjuly ...

输出

  • best dentist in july is...(基本上用给定字典的空格分隔非空格字符串)

解决它的最佳算法是什么?

一个微妙但重要的问题是,是否有任何奇特的方法来解决无法到达的死胡同问题。例如,dendentist都是有效的词来剖析其余的字符串,其中一个可能只是一个死胡同。

对我而言,这似乎是一个贪婪的问题或动态编程可以解决的问题。

6 个答案:

答案 0 :(得分:2)

使用Trie存储字典。您可以在How to create a trie in c#

看到一个简单的实现(C#)

您需要进行搜索,因为在考虑整个输入字符串之前,您不知道自己是否在正确的轨道上。你需要迭代输入字符串,同时下降到trie中。当你到达特里的终端节点时,你的搜索过程中有一个分支:你需要将它视为单词的结尾并将其视为较长单词的第一部分。

答案 1 :(得分:2)

您可以创建一种词树:

你可以通过没有空格的字符串。一旦你在列表中找到一个单词,你就可以添加一个空格并继续...直到你无法继续前进。

然后你回到上一个单词并尝试添加新单词,你可以创建一个单词,如果你可以从他们继续。

你试试这个,直到你尝试了所有可能性。

如果你回到起始单词并且找不到任何解决方案=>没有溶胶

这是算法(我的伪代码语法不好,但你可以得到一般的想法。我相信你必须纠正一点):

TreeWordResult //Tree that keeps the results in memory

Go through the InputString:

      If you find a word in the InputDictionnary 
          Then add this word to the last node of the treeWordResult
      Otherwise:
          while (No word found):
                go back in the treeWordResult
                try to find word in InputDictionnary different from the one before (on the other node)
          endwhile
          if no word found:
                     return NO SOLUTION
          otherwise:
                     continue going through word
          endif
       endif
 return Leaf   

算法在你找不到溶胶时结束,或当你在“叶子”(你穿过整个字符串)时结束

以下是使用您的示例的插图:

enter image description here

希望我的解释清楚。

答案 2 :(得分:1)

这个问题基本上就像匹配表单的正则表达式一样:

(in|july|den|dentis|best|...)*

因此可以使用任何正则表达式算法。您应该选择哪个取决于字典的大小和输入的长度。你应该从这里开始:http://en.wikipedia.org/wiki/Regular_expression#Implementations_and_running_times

答案 3 :(得分:1)

我认为如果你能让findWord方法为'not-a-word'和'no-words-starting-with-this-prefix'返回不同的值,你可以加快速度。如果字典存储为trie,这将很容易。

原因是 如果你在@Ricky Bobby的答案中检查单词,在找到'best'之后,你仍然需要检查'bestd'和'bestde'等等一直到字符串的结尾。但是,如果检查'bestd'返回'no-more-words',那么你已经完成了一大堆搜索。

答案 4 :(得分:0)

目前尚不清楚原始帖子究竟要解决什么问题。我猜@Figo正在寻找类似于字符串匹配算法的东西。

非常好的资源:http://igm.univ-mlv.fr/~lecroq/string/

答案 5 :(得分:0)

也许有多个有效的解决方案来分隔输入字符串。您可以使用backtracking algorithm找到一个或所有有效的解决方案。在两个或多个单词的位置,例如“den”,“牙医”是可能的,算法应首先尝试较长的单词。

当然字典应该存储在Trie中,以便快速找到匹配的单词。

在下面的ascii图像中,首先会在Depth-first search中检查左侧分支,它更喜欢较长的单词。在算法使用单词“den”查看右侧分支之前,可以找到解决方案。


        Best
        /   \
   dentist  den
      /
     in
    /
  july