在C#中匹配两大字符串

时间:2010-01-19 20:55:04

标签: c# sql search dictionary

情况如下:

我有一个网页,我已经把它作为一个字符串。

我在MSSQL数据库中有几个字段。例如,汽车模型,它有一个ID和一个名称,如Mustang或Civic。它预装了大多数车型。

我想找到我的模型表中任何行的匹配项。所以,如果我在我的模型表中有Civic,Mustang和E350,我想找到我已经刮过的页面中任何三个中的任何一个。

在C#中执行此操作的有效方法是什么?我正在使用LINQ to SQL与db进行交互。

创建所有模型的字典,标记页面和迭代标记是否有意义?或者我应该迭代标记并使用WHERE子句并询问数据库是否匹配?

    //Dictionary dic contains all models from the DB, with the name being the key and the id being the value...
    foreach(string pageToken in pageTokens)
    {
         if(dic.ContainsKey(pageToken)) 
         {
              //Do what I need to do
         }
    }

这两种方法对我来说都很糟糕。关于我应该做什么的任何建议?设想交叉点的东西我觉得可能会很好吗?

这两种方法都没有解决当模型名称多于一个单词时发生的情况。如“F150 Extended Cab”。对此的想法?

4 个答案:

答案 0 :(得分:5)

在较大的文本中搜索多个字符串是一个众所周知的问题,并且已经进行了大量研究以使其快速进行。对此最常用和最有效的两种方法是Aho-Corasick Algorithm(我推荐这个)和Rabin-Karp Algorithm。他们使用了一些预处理,但是数量级不那么复杂。比naieve方法更快(naieve方法是最坏情况O(m * n ^ 2 * p),其中m是长串[你刮的网页]的长度,n是针的平均长度,p是针数)。 Aho-Corsaik是线性的。 A C# implementation of it can be found at CodeProject for free.

编辑:哎呀,我错了Aho-Corasick的复杂性 - 它的数字和数字是线性的。输入字符串的长度+正在分析的字符串的大小[已删除的文本]加上匹配的数量。但它仍然是线性的,线性比立方更好: - )。

答案 1 :(得分:3)

我的第一种方法是超级简单:

foreach(string carModel in listOfCarModelsFromDatabase) {
    if(pageText.Contains(carModel) {
        // do something
    }
}

如果上述速度不够快,我只会开始担心如何加快速度。汽车模型列表不可能是那么大(<10000?)而且它只是一页文本。

答案 2 :(得分:0)

您应该使用正则表达式,而不是基于空格进行标记。

使用Regex你可以使用空格并且很好,我相信它会比标记化和循环遍历可能的值列表更快。

虽然我不确定如何构建该正则表达式。

最简单的说,您可以使用

等每个模型构建一个正则表达式
(Model 1|Model 2|Model 3) 

但我确信在正则表达式中有更有效的方法可以做到这一点。

答案 3 :(得分:0)

对于一个非常简单的子串匹配解决方案(应该运行得相当好),你可以使用这样的参数化SQL查询:

select ModelID, ModelName
from Model
where ? like '%' + ModelName + '%'

其中?是一个被整个网页文本替换的参数。