在一组单词中查找匹配的短语

时间:2016-06-30 11:17:50

标签: algorithm word-frequency

我创建了一个程序来解析一些文本文件并计算单词数量然后按降序排序。这很有效,但我想把它提升到另一个层次。

我希望能够找到重复的文字中的任何单词短语,我不知道如何去做。

我目前的算法是首先将文本拆分为单词,然后使用单词和计数创建一个哈希表,如下所示:key

hash:
    "word":3,
    "test":12,
     .....

然后我只根据键和输出对has进行排序,我就完成了。

假设我有这首生日快乐歌:

Happy Birthday to You
Happy Birthday to You
Happy Birthday Dear (name)
Happy Birthday to You.

From good friends and true,
From old friends and new,
May good luck go with you,
And happiness too.

Alternative ending:
How old are you?
How old are you?
How old, How old
How old are you?

我可以得到单词计数很好,但如果我想匹配所有短语怎么办?

例如,这个6个单词的短语可以说是匹配两次:

happy birthday to you happy birthday

一对5字短语匹配:

birthday to you happy birthday
happy birthday to you happy

一些4个单词的短语匹配

how old are you
happy birthday to you
to you happy birthday
how old how old
birthday to you happy

依此类推两个匹配的单词短语。

我更关心整个短语的匹配,即使是跨行,因为我必须查看输出以进行进一步处理。

什么类型的算法可以让我实现这个目标?

2 个答案:

答案 0 :(得分:1)

首先,您可能希望使用快速正则表达式对通道进行标记,以便更轻松地迭代单词,例如在所有空格/换行符上使用您的语言的String.split方法。这应该留下像这样的String数组:["Happy", "birthday", "to", "you", "happy", ...]。如果你以后使用正则表达式,你不会需要对字符串进行小写,我在这个答案中建议。

在此之后,您需要从段落中提取短语,您可以通过创建startend指针来实现这些短语并按以下方式迭代:

for (var start = 0; start < tokens.length; start+=1) {
    for (var end = start; end < tokens.length; end+=1) {
        var phrase = tokens.slice(start, end)
        // Count occurrences of phrase ...
    }
}

以上将使用每个单词作为提取的起点,并将每个后续单词用作提取的终点,这允许在phrase中拾取单个单词和整个短语。请注意,这些短语(如果我的数学是正确的)(n + n ^ 2)/ 2,所以这个东西有指数增长。如果你积极地存储所有短语直到最后,内存使用量可能会对大数据非常大。

正则表达式匹配本身可以找到给定短语的出现次数,因此您不限于使用哈希表来存储您的工作结果。只需在段落中存储多个出现的短语,就可以节省内存。

答案 1 :(得分:0)

您可以使用与单词组合相同的算法。 如果你使用最大大小为n的队列,你可以连续检查最后n个单词(例如通过迭代器)并将它们添加到你的哈希表中。 对n = 2重复此操作,直到n> 1。 (你的#words / 2)或没有发现重复

实施例 “W1 w2 w3, W3 w1 w2。“

应该给出哈希表.. HASH2:    “w1 w2”:2    “w2 w3”:1    “w3 w3”:1    “w3 w1”:1 ..for n = 2(忽略大写字母和逗号) 对于n = 3,您的最高计数为1,您可以打破

清理换行符中的换行符并在连接时使用aditional空格