コースの名前を保存するために使用される名前があります。次の方法を使用してコースを見つけていますStringBuilder
。stb_Swap_Tabu
stb_Swap_Tabu.ToString.Contains("CourseName")
私の場合、パフォーマンスが最も重要な問題です。より速い方法はありますか?
コースの名前を保存するために使用される名前があります。次の方法を使用してコースを見つけていますStringBuilder
。stb_Swap_Tabu
stb_Swap_Tabu.ToString.Contains("CourseName")
私の場合、パフォーマンスが最も重要な問題です。より速い方法はありますか?
StringBuilder は、実際にはすべての文字列の目的を意図したものではありませんでした。本当に検索する必要がある場合は、独自のメソッドを作成する必要があります。
さまざまなケースに適した文字列検索アルゴリズムがいくつかあります。
以下は、序数の一致のみを考慮する Knuth–Morris–Pratt アルゴリズムの単純な実装です (大文字と小文字の組み合わせ、カルチャに関連した照合は行われず、単純なコードポイント間の一致のみ)。検索された単語の長さである初期Θ(m)
オーバーヘッドがm
あり、検索された単語までの距離、または文字列ビルダー全体の長さが存在しない場合は、Θ(n)
どこで検索されます。n
これは単純な char-by-char の比較に勝りますΘ((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;
}
}