Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 检查字符串是否包含(字符串)列表中的元素_C#_Vb.net_List_Coding Style_Performance - Fatal编程技术网

C# 检查字符串是否包含(字符串)列表中的元素

C# 检查字符串是否包含(字符串)列表中的元素,c#,vb.net,list,coding-style,performance,C#,Vb.net,List,Coding Style,Performance,对于以下代码块: For I = 0 To listOfStrings.Count - 1 If myString.Contains(lstOfStrings.Item(I)) Then Return True End If Next Return False 输出为: 案例1: myString:C:\Files\myfile.doc 列表字符串:C:\Files\,C:\Files2\ 结果:正确 案例2: myString:C:\Files3\myfil

对于以下代码块:

For I = 0 To listOfStrings.Count - 1
    If myString.Contains(lstOfStrings.Item(I)) Then
        Return True
    End If
Next
Return False
输出为:

案例1:

myString:C:\Files\myfile.doc
列表字符串:C:\Files\,C:\Files2\
结果:正确
案例2:

myString:C:\Files3\myfile.doc
列表字符串:C:\Files\,C:\Files2\
结果:错误
列表(listOfStrings)可能包含多个项目(至少20个),必须对照数千个字符串(如myString)进行检查

有没有更好(更有效)的方法来编写此代码?

使用LINQ,并使用C#(我现在对VB了解不多):

或者(更短、更高效,但可以说不那么清晰):

如果您正在测试相等性,那么值得查看
HashSet
等,但这对部分匹配没有帮助,除非您将其拆分为片段并添加复杂性顺序



更新:如果你的意思是“StartsWith”,那么你可以对列表进行排序并将其放入数组中;然后使用
Array.BinarySearch
查找每个项目-通过查找查看它是否完全匹配或部分匹配。

前面的一个类似问题“”给出了许多建议

正则表达式可能足以满足您的要求。表达式将是所有候选子字符串的串联,它们之间有一个OR“
|
”运算符。当然,在构建表达式时,您必须注意未转义的字符,或者由于复杂性或大小限制而无法编译


另一种方法是构造一个表示所有候选子字符串(这可能与正则表达式匹配器所做的有些重复)。在逐步遍历测试字符串中的每个字符时,您将创建一个指向trie根的新指针,并将现有指针前进到相应的子级(如果有)。当任何指针到达某个叶子时,都会得到一个匹配。

根据您的模式,一个改进是使用StartsWith而不是Contains。StartsWith只需遍历每个字符串,直到找到第一个不匹配项,而无需在找到一个字符位置时重新启动搜索

此外,根据您的模式,您可能可以提取myString路径的第一部分,然后反向比较——在字符串列表中查找myString的起始路径,而不是相反

string[] pathComponents = myString.Split( Path.DirectorySeparatorChar );
string startPath = pathComponents[0] + Path.DirectorySeparatorChar;

return listOfStrings.Contains( startPath );
EDIT:使用HashSet idea@Marc Gravell提到的方法会更快,因为您可以将
Contains
更改为
ContainsKey
,并且查找将是O(1)而不是O(N)。您必须确保路径完全匹配。请注意,这不是@Marc Gravell的一般解决方案,而是根据您的示例定制的


对于C#示例,我感到抱歉。我没有足够的咖啡来翻译成VB。

如果速度很关键,您可能需要查找模式集


它是一个包含失败链接的函数,即复杂度为O(n+m+k),其中n是输入文本的长度,m是模式的累积长度,k是匹配数。您只需修改算法,在找到第一个匹配后终止。

您测试过速度了吗

i、 e.您是否创建了数据样本集并对其进行了分析?它可能没有你想象的那么糟糕


这也可能是一些你可以衍生到一个单独的线程,并给速度的错觉

我喜欢Marc的答案,但需要Contains匹配不区分大小写

myList.Any(myString.Contains);
这就是解决方案:

bool b = listOfStrings.Any(s => myString.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0))

当你构造你的字符串时,它应该是这样的

bool inact = new string[] { "SUSPENDARE", "DIZOLVARE" }.Any(s=>stare.Contains(s));

Contains
方法的缺点是不允许指定比较类型,这在比较字符串时通常很重要。它总是区分区域性和大小写。所以我认为WhoIsRich的答案很有价值,我只想展示一个更简单的选择:

listOfStrings.Any(s => s.Equals(myString, StringComparison.OrdinalIgnoreCase))

老问题。但是由于
VB.NET
是最初的需求。使用与接受答案相同的值:

listOfStrings.Any(Function(s) myString.Contains(s))

由于我需要检查列表中是否有(长)字符串中的项目,因此我最终得出以下结论:

listOfStrings.Any(x => myString.ToUpper().Contains(x.ToUpper()));
或在vb.net中:

listOfStrings.Any(Function(x) myString.ToUpper().Contains(x.ToUpper()))

稍有变化,我需要找出字符串中是否有完整的单词和不区分大小写的字符

myString.Split(' ', StringSplitOptions.RemoveEmptyEntries).Intersect(listOfStrings).Any())

对于不区分大小写的
myString
listofstring
已转换为大写。

根据他的示例,我将使用StartsWith代替Contains。@tvanfosson-这取决于示例是否完全包含,但我同意。当然,更改很简单。这段代码在算法层面上效率有多高?如果“Any”中的循环更快,它会更短更快,但您必须多次执行精确匹配的问题是相同的。如果您使用集合,您可以设置自定义比较器。第二个比较器在实践中并没有任何可测量的差异,因此其效率也不会更高。重新开始;也许预先排序并使用二进制搜索?这可能会更快。它不应该是>-1吗?@CSharped并不重要,因为>-1(大于-1)和>=0(大于或等于零)是一回事。
listOfStrings.Any(Function(x) myString.ToUpper().Contains(x.ToUpper()))
myString.Split(' ', StringSplitOptions.RemoveEmptyEntries).Intersect(listOfStrings).Any())