【问题标题】:Word by word phrase matching逐字词组匹配
【发布时间】:2016-02-05 23:01:33
【问题描述】:

我需要在 C 中实现一个算法来进行短语匹配/短语识别。具体来说,我有一个循环运行的函数,它输出以逐字筛选字符串。我将每个输出字放在缓冲区中。 我还有一个文件,其中包含一组这样的短语:

短语 1:早上好,[姓氏] [名字]先生,您的帐户中有 [金额] $。

短语 2:成员 [last name] [first name] 已从列表中选择了 [option]

所以我的短语有一个已知的形式,由固定部分和动态部分组成(在“[”“]”之间)。关于动态部分,我只知道组成它的单词数。例如,在短语 2 中,第一个动态部分有 2 个单词,第二个动态部分有一个单词。

由于我的缓冲区充满了函数输出中的单词,我需要确定列表中的哪个短语与缓冲区匹配。

如果已经有这样的算法,我需要关于可以使用的算法的建议,如果没有,在 C 中执行此操作的最佳方法是什么?

谢谢。

【问题讨论】:

  • 你试过什么?你能发布一些代码吗?问题的措辞有点尴尬,我不完全确定您要达到的目标
  • 如果我理解正确,您拥有的唯一信息是缓冲区应包含与短语匹配的单词数。假设单词是由 ​​SPACE 分隔的字符串,你可以计算出缓冲区中有多少单词,并找到对应的短语。还是我误解了这个问题?
  • 我有一个带循环的函数。在每次迭代中,都会在缓冲区中添加一个新单词。单词用空格隔开。所以我知道每时每刻的缓冲区内容,也知道我正在寻找的列表中的短语。
  • 你能贴一些代码吗?
  • 我的想法:将列表中的所有短语放在一个矩阵中,在每个字段上存储一个单词。然后,当缓冲区接收到第一个单词时,我将遍历矩阵中的第一列以从缓冲区中搜索单词(仅存储匹配的行)。这样,我将确定哪些短语以这个词开头。然后,当缓冲区接收到第二个单词时,我将仅在上一步存储的行上遍历第二列。现在我将确定哪些短语以缓冲区中的前两个单词开头。该算法将继续进行,直到在我的矩阵中保持单行。

标签: c regex algorithm string-matching


【解决方案1】:

我会从一个像这样的锯齿状字符指针数组开始

char *phrase1[] = { "Good", "morning", "Mr.", "", "", "you", "have", "", "$", "in", "your", "account.", NULL };
char *phrase2[] = { "Member", "", "", "has", "chosen", "", "from", "the", "list.", NULL };
char **phrases[] = { phrase1, phrase2, NULL };

在每个短语中,都有

  • 必须完全匹配的单词,例如"morning"
  • 空字符串"" 标记动态项的位置
  • NULL 标记短语结尾的指针

使用数组时,phrases[p][i] 是短语 p 中的第 i 个单词,
phrases[p][i][0] 是短语 p 中第 i 个单词的第一个字符。

因此,检查动态项目的代码是

if ( phrases[p][i][0] == '\0' )
    // this is a dynamic item

检查词组的结尾

if ( phrases[p][i] == NULL )
    // this is the end of the phrase

否则,比较单词

if ( strcmp( phrases[p][i], word ) == 0 )
    // the word matches 

【讨论】:

  • 谢谢,我明白了,从这一点上应该没问题。非常感谢!
【解决方案2】:

假设缺失的单词遵循已知的regex 模式,例如[\w\d]+,您可以创建一个 big 正则表达式,格式如下:

^(Good morning Mr. [\w\d]+ [\w\d]+ you have [\w\d]+ \$ in your account.)
|(Member [\w\d]+ [\w\d]+ has chosen [\w\d]+ from the list.)
|(...)$

然后将此正则表达式与输入进行匹配将告诉您匹配哪个子表达式,并且子表达式的索引匹配短语的索引。

这正是flex 在内部所做的。因此,另一种可能性是将匹配的短语作为正则表达式写入 flex 文件并要求 flex 为您生成匹配器。

【讨论】:

    猜你喜欢
    • 2016-09-26
    • 2019-07-25
    • 2016-10-10
    • 2023-04-09
    • 1970-01-01
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    • 2019-03-12
    相关资源
    最近更新 更多