我有一个名为 stb_Swap_Tabu
的 StringBuilder
,用于存储课程名称,
我正在使用以下方法查找一门课程:
stb_Swap_Tabu.ToString.Contains("CourseName")
在我的情况下,性能是最重要的问题。 是否有更快的方法?
我有一个名为 stb_Swap_Tabu
的 StringBuilder
,用于存储课程名称,
我正在使用以下方法查找一门课程:
stb_Swap_Tabu.ToString.Contains("CourseName")
在我的情况下,性能是最重要的问题。 是否有更快的方法?
StringBuilder并不是为所有字符串目的而设计的。如果你真的需要搜索一个,你必须编写自己的方法。
有几种适用于不同情况的字符串搜索算法。
以下是Knuth-Morris-Pratt算法的简单实现,它只关心序数匹配(没有大小写转换,没有与文化相关的排序,只是一个纯粹的代码点到代码点的匹配)。它有一些初始的Θ(m)
开销,其中m
是所需单词的长度,然后在Θ(n)
中找到所需单词的距离或整个字符串构建器的长度,如果它不存在的话。这击败了简单的逐字符比较,其复杂度为Θ((n-m+1) m)
(其中O()
符号描述上限,Θ()
描述上下限)。
尽管如此,创建一个列表似乎更好地解决了手头的任务。
public static class StringBuilderSearching
{
public static bool Contains(this StringBuilder haystack, string needle)
{
return haystack.IndexOf(needle) != -1;
}
public static int IndexOf(this StringBuilder haystack, string needle)
{
if(haystack == null || needle == null)
throw new ArgumentNullException();
if(needle.Length == 0)
return 0;//empty strings are everywhere!
if(needle.Length == 1)//can't beat just spinning through for it
{
char c = needle[0];
for(int idx = 0; idx != haystack.Length; ++idx)
if(haystack[idx] == c)
return idx;
return -1;
}
int m = 0;
int i = 0;
int[] T = KMPTable(needle);
while(m + i < haystack.Length)
{
if(needle[i] == haystack[m + i])
{
if(i == needle.Length - 1)
return m == needle.Length ? -1 : m;//match -1 = failure to find conventional in .NET
++i;
}
else
{
m = m + i - T[i];
i = T[i] > -1 ? T[i] : 0;
}
}
return -1;
}
private static int[] KMPTable(string sought)
{
int[] table = new int[sought.Length];
int pos = 2;
int cnd = 0;
table[0] = -1;
table[1] = 0;
while(pos < table.Length)
if(sought[pos - 1] == sought[cnd])
table[pos++] = ++cnd;
else if(cnd > 0)
cnd = table[cnd];
else
table[pos++] = 0;
return table;
}
}
return m;
,而不是 return m == needle.Length ? -1 : m;
吗? - Juri Roblreturn m;
。否则它会返回 -1。 - neilsimp1我知道这是一个老问题,但当我尝试为自己的项目创建解决方案时,它出现在我的搜索结果中。我以为我需要搜索StringBuilder.ToString
方法的结果,但后来我意识到我可以直接调用StringBuilder
本身的方法。我的情况可能与你的不同,但我想分享一下:
Private Function valueFormatter(ByVal value As String) As String
' This will correct any formatting to make the value valid for a CSV format
'
' 1) Any value that as a , in it then it must be wrapped in a " i.e. Hello,World -> "Hello,World"
' 2) In order to escape a " in the value add a " i.e. Hello"World -> Hello""World
' 3) if the value has a " in it then it must also be wrapped in a " i.e. "Hello World" -> ""Hello World"" -> """Hello World"""
'
' VB NOTATAION
' " -> """"
' "" -> """"""
If value.Contains(",") Or value.Contains("""") Then
Dim sb As New StringBuilder(value)
If value.Contains("""") Then sb.Replace("""", """""")
sb.Insert(0, """").Append("""")
Return sb.ToString
Else
Return value
End If
End Function
StringBuilder
,那么每次想要搜索时都需要调用ToString
,这在性能方面并不是一个好主意。StringBuilder
用于构建字符串;假设你正在构建字符串,那么你已经有了组成部分;为什么不直接在这些组成部分中进行搜索呢? - LukeHStringBuilder
可能不是存储可搜索名称列表的最合适数据类型。为什么不使用List<string>
,并使用List
的Contains
方法? - RotemList<string>
或HashSet<string>
将会有很多意义。 - Marc GravellHashSet
,较少的字符串使用list
。 - Chibueze Opata