StringBuilder中最快的搜索方法

时间:2012-09-04 10:15:43

标签: c# .net vb.net performance stringbuilder

我有一个名为StringBuilder的{​​{1}},用于存储课程名称, 我使用以下方法查找课程:

stb_Swap_Tabu

就我而言,性能是最重要的问题。 有没有更快的方法?

2 个答案:

答案 0 :(得分:24)

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;
  }
}

答案 1 :(得分:1)

我知道这是一个老问题,但当我试图为我自己的项目创建一个解决方案,我认为我需要搜索一个字符串构建器时,它出现在我的搜索结果中,但后来我意识到我可以只搜索那个值我用来初始化字符串生成器。所以我的情况可能与你的情况不一样,但我虽然分享了:

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