c#-带通配符的二进制搜索字符串列表

c#-带通配符的二进制搜索字符串列表,c#,search,tstringlist,C#,Search,Tstringlist,我有一个已排序的字符串列表,希望替换 foreach (string line3 in CardBase.cardList) if (line3.ToLower().IndexOf((cardName + Config.EditionShortToLong(edition)).ToLower()) >= 0) { return true; } 使用binarySearch,因为card

我有一个已排序的字符串列表,希望替换

foreach (string line3 in CardBase.cardList)
            if (line3.ToLower().IndexOf((cardName + Config.EditionShortToLong(edition)).ToLower()) >= 0)
            {
                return true;
            }
使用binarySearch,因为cardList相当大(~18k),而此搜索占用了大约80%的时间

所以我找到了List.BinarySearch-Methode,但我的问题是cardList中的行如下所示:

Brindle_Boar_(Magic_2012).c1p247924.prod
但是我没有办法生成c1p,这是一个问题,因为List.BinarySearch只查找完全匹配的项

如何修改List.BinarySearch,使其在只有部分字符串匹配时才能找到匹配项

e。G 搜索Brindle_Boar_(Magic_2012)应返回Brindle_Boar_(Magic_2012)的位置。c1p247924.prod

BinarySearch()
有一个重载,该重载接受一个
IComparer
有第二个参数,实现一个自定义比较器,当字符串中有匹配项时返回0-您可以使用相同的
IndexOf()
方法

编辑:


二进制搜索在您的场景中有意义吗?如何确定某个项目比另一个项目“少”或“大”?现在,您只提供构成匹配的内容。只有在您能够回答此问题时,二进制搜索才会首先应用。

列表。如果未找到精确匹配项,则二进制搜索将返回下一个大于请求项的索引补码

因此,您可以这样做(假设您永远无法获得精确匹配):


您可以查看(也可以通过NuGet安装)。 使用SorterDarray(T)类型进行收集。它提供了一些可能被证明有用的方法。您甚至可以非常高效地查询项目范围

var data = new SortedArray<string>();

// query for first string greater than "Brindle_Boar_(Magic_2012)" an check if it starts 
// with "Brindle_Boar_(Magic_2012)"
var a = data.RangeFrom("Brindle_Boar_(Magic_2012)").FirstOrDefault();
return a.StartsWith("Brindle_Boar_(Magic_2012)");

// query for first 5 items that start with "Brindle_Boar"
var b = data.RangeFrom("string").Take(5).Where(s => s.StartsWith("Brindle_Boar"));

// query for all items that start with "Brindle_Boar" (provided only ascii chars)
var c = data.RangeFromTo("Brindle_Boar", "Brindle_Boar~").ToList()

// query for all items that start with "Brindle_Boar", iterates until first non-match
var d = data.RangeFrom("Brindle_Boar").TakeWhile(s => s.StartsWith("Brindle_Boar"));
var data=new SortedArray();
//查询大于“Brindle_Boar_(Magic_2012)”的第一个字符串,检查是否开始
//与“布林德尔•野猪”(魔法•2012)
var a=data.RangeFrom(“Brindle_Boar_(Magic_2012)”).FirstOrDefault();
返回a.StartsWith(“Brindle_Boar_(Magic_2012)”);
//查询以“Brindle_Boar”开头的前5项
VarB=data.RangeFrom(“string”).Take(5).式中(s=>s.StartsWith(“布林德尔_野猪”);
//查询以“Brindle_Boar”开头的所有项目(仅提供ascii字符)
var c=data.RangeFromTo(“布林德尔野猪”,“布林德尔野猪~”).ToList()
//对以“Brindle_Boar”开头的所有项的查询将迭代到第一个不匹配项
var d=数据。范围从(“布林德尔野猪”)。TakeWhile(s=>s.StartsWith(“布林德尔野猪”);

拉格弗洛姆。。。方法执行二进制搜索,找到大于或等于参数的第一个元素,该元素从该位置返回迭代器

我想知道,如果出于比较目的而丢弃cp1部分,是否会破坏原始顺序,也就是说,在去掉cp1位后能否获得不同的顺序?在这种情况下,您可能会得到误判。@chibacity:再次审视这个问题,我认为字符串匹配只有在索引0开始时才有意义-否则您是对的,它将导致不同的隐含顺序,从而中断二进制搜索。我已经说过,我将使用
StartsWith()
而不是
IndexOf()
这对于StartsWith搜索大字符串(甚至是数据,如果您在某些类上实现了IComparable)集是绝对完美的。只需执行
var from=list.BinarySearch(str);var to=list.BinarySearch(str+char.MaxValue)然后,如果索引小于零,则将
~
应用到
索引中(对于
应用负一)。我不知道BinarySearch有这么酷的功能。
var data = new SortedArray<string>();

// query for first string greater than "Brindle_Boar_(Magic_2012)" an check if it starts 
// with "Brindle_Boar_(Magic_2012)"
var a = data.RangeFrom("Brindle_Boar_(Magic_2012)").FirstOrDefault();
return a.StartsWith("Brindle_Boar_(Magic_2012)");

// query for first 5 items that start with "Brindle_Boar"
var b = data.RangeFrom("string").Take(5).Where(s => s.StartsWith("Brindle_Boar"));

// query for all items that start with "Brindle_Boar" (provided only ascii chars)
var c = data.RangeFromTo("Brindle_Boar", "Brindle_Boar~").ToList()

// query for all items that start with "Brindle_Boar", iterates until first non-match
var d = data.RangeFrom("Brindle_Boar").TakeWhile(s => s.StartsWith("Brindle_Boar"));