我有一个非常长的字符串(数千行)。我正在对字符串运行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
答案 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();
}
这将从字典中创建一组值,其中键位于特定范围内。