C#Dictionary快速搜索最接近键值

时间:2013-09-04 16:30:43

标签: c# regex dictionary

我有一个非常长的字符串(数千行)。我正在对字符串运行RegEx表达式并尝试识别匹配的行号。但是,如果我有一个高匹配计数(比如10,000),那么每次查找行号时都会再次搜索html字符串,这会很昂贵。

我想要做的是事先搜索字符串并构建行号字符位置的哈希表。所以我可以使用Dictionary并使用以下代码来查找我的行号。

//find line endings
int lineCount = 0;
for (int charCount = 0; charCount <= html.Length; charCount++)
{
     if (html[charCount] == '\n')
     {
         lineCount++;
         lineEndings.Add(charCount, lineCount);
     }
}

但是,当我运行我的RegExes时,如何搜索这个字典?正则表达式表达式字符位置需要在之间在lineEndings字典中的两个值之间。什么是最好/最有效的方式;给定一个带有一组间隙键的字典,给定一个不在键列表中的值,找到下一个最近的键?

我尝试过的一件事,我不确定它会如何表现,是

lineEndings.First(n => n.Key >= match.Index).Value

2 个答案:

答案 0 :(得分:2)

当“等于”的定义只是“接近”时,词典不起作用。

字典中的项目必须是变性的。如果A = B且B = C则A应该等于C.如果不是这种情况(不是这样,如果相等被定义为“接近”,则事情开始崩溃。

首先,您无法在此处编写有效的GetHashCode实施方案。它永远有效的唯一方法是让一切都返回相同的值,这意味着你只是将性能降低到线性搜索。

如果您有一组静态字符串,您可以将它们全部放在List或数组中,对它们进行排序,然后使用BinarySearch。由于数据看起来是静态的,因此将项目添加到查找表的成本非常高,这应该不是问题。二进制搜索还能够告诉您要搜索的项目属于哪个属性(如果应该添加),这意味着您可以转到该位置的索引以查找“下一个”项目,并减去一个以查找“之前的“项目。

答案 1 :(得分:1)

如果你知道你想要键的范围,你可以在你的字典中使用LINQ。这样的事情:

    Dictionary<int, string> Test1 = new Dictionary<int, string>();
    public Form1()
    {
        InitializeComponent();
        Test1.Add(1, "asdf");
        Test1.Add(2, "ghjh");
        Test1.Add(3, "jkl;");
        Test1.Add(4, "qwer");

        int max = 4;
        int min = 1;
        listBox1.DataSource = (from kvp in Test1
                               where (kvp.Key > min && kvp.Key < max)
                               select (kvp.Value)).ToList();

    }

这将从字典中创建一组值,其中键位于特定范围内。