最好的方法是针对一个大的可比较列表进行现有字符串的测试。

8 浏览
0 Comments

最好的方法是针对一个大的可比较列表进行现有字符串的测试。

假设您有一组缩写词,用于定义一个值(例如AB1,DE2,CC3),您需要检查一个字符串值(例如“Happy:DE2 | 234”),以查看该字符串中是否包含缩写词。对于缩写词的短列表,我通常会创建一个使用分隔符的简单正则表达式(例如(AB1 | DE2 | CC3)),并寻找匹配项。

但是如果有超过30个缩写词需要匹配怎么办?使用相同的技术是否有意义(很丑),还是有更有效和优雅的方法来完成此任务?

请记住,示例缩写词列表和示例字符串并不是我正在使用的实际数据格式,而只是表达我的挑战的方式。

顺便说一句,我阅读了SO相关问题,但认为它不适用于我试图完成的任务。

编辑:我忘记包括捕获匹配值的需求,因此选择使用正则表达式......

admin 更改状态以发布 2023年5月24日
0
0 Comments

如果缩写词具有固定的大小(如上例所示),您可以为它们计算哈希值(可以在应用程序生命周期内执行一次),然后将字符串分成重叠的部分并为它们计算哈希值。然后,您只需要在一个数组中搜索另一个数组中的值。

您可能还可以从缩写词创建后缀/前缀树或类似的东西,并使用此信息进行搜索,在维基百科中有很多算法可做到这一点。

您还可以为每个缩写词创建确定性自动机,但这与前一种方法非常相似。

0
0 Comments

就我个人而言,我认为正则表达式中30并不算太大,所以不应该太快排除它。你可以用一行代码来创建正则表达式:

var acronyms = new[] { "AB", "BC", "CD", "ZZAB" };
var regex = new Regex(string.Join("|", acronyms), RegexOptions.Compiled);
for (var match = regex.Match("ZZZABCDZZZ"); match.Success; match = match.NextMatch())
    Console.WriteLine(match.Value);
// returns AB and CD

因此,这段代码相对优雅且易于维护。如果你知道缩写的数量的上限,可以进行一些测试,谁知道正则表达式引擎中已经内置了什么样的优化。你还将免费受益于将来的正则表达式引擎优化。除非你有理由相信性能将成为问题,否则保持简单。

另一方面,正则表达式可能会有其他限制,例如默认情况下,如果你有缩写AB,BC和CD,则在“ABCD”中它只会返回其中两个作为匹配。所以它很擅长告诉你有缩写,但你需要小心捕捉多个匹配。

当性能成为我的问题(> 10,000项)时,我将“缩写”放入了哈希集中,然后搜索文本的每个子字符串(从最小的缩写长度到最大的缩写长度)。这对我来说还可以,因为源文本非常短。我之前没有听说过,但初步看来,你提到的问题中引用了的Aho-Corasick算法似乎是这个问题的更好的通用解决方案。

0