我有一個名爲stb_Swap_Tabu
一個StringBuilder
用來存放課程的名稱, 我使用下面的方法找到一門課程:最快的搜索方法的StringBuilder
stb_Swap_Tabu.ToString.Contains("CourseName")
在我的情況
,性能是最重要的問題。 有沒有更快的方法?
我有一個名爲stb_Swap_Tabu
一個StringBuilder
用來存放課程的名稱, 我使用下面的方法找到一門課程:最快的搜索方法的StringBuilder
stb_Swap_Tabu.ToString.Contains("CourseName")
在我的情況
,性能是最重要的問題。 有沒有更快的方法?
StringBuilder並非真正用於所有字符串目的。如果你真的需要搜索一個,你必須編寫你自己的方法。
有幾種適用於不同情況的字符串搜索算法。
以下是Knuth-Morris-Pratt算法的一個簡單實現,它只關心序數匹配(沒有案例摺疊,沒有文化相關的排序規則,只是代碼點匹配的簡單代碼點)。它有一些初始的Θ(m)
開銷,其中m
是所尋找單詞的長度,然後在Θ(n)
中找到,其中n
是尋找單詞的距離,或者是整個字符串生成器的長度(如果它不存在)。這比簡單的char-by-char比較要好得多(其中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;
}
}
我知道這是一個老問題,但在當時我是想,我認爲我需要尋找一個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'用於*構建字符串*;大概如果你正在建造琴絃,那麼你已經有了組成部分;你爲什麼不直接在這些組成部分內進行搜索? – LukeH
'StringBuilder'可能是最不適合存儲可搜索名稱列表的數據類型。爲什麼不用'List'代替,並使用'List'的'Contains'方法? –
Rotem
你有一個這個字符串實際是什麼的例子嗎?你說它存儲「課程名稱」 - 「課程」實際上是否意味着「課程」,「名稱」建議不止一個名稱 - 所以推測這是一個分隔字符串。在這種情況下,將其切換到*個人*名稱的'List'或'HashSet '將對大數字的字符串產生很大的意義 –