Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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# StringBuilder中最快的搜索方法_C#_.net_Vb.net_Performance_Stringbuilder - Fatal编程技术网

C# StringBuilder中最快的搜索方法

C# StringBuilder中最快的搜索方法,c#,.net,vb.net,performance,stringbuilder,C#,.net,Vb.net,Performance,Stringbuilder,我有一个名为stb\u Swap\u Tabu的StringBuilder用于存储课程名称, 我正在使用以下方法查找课程: stb_Swap_Tabu.ToString.Contains("CourseName") 就我而言,性能是最重要的问题。 有没有更快的方法?StringBuilder并不是真的用于所有字符串目的。如果您真的需要搜索一个,您必须编写自己的方法 有几种适合不同情况的字符串搜索算法 下面是Knuth–Morris–Pratt算法的一个简单实现,该算法只关心顺序匹配(没有大小写

我有一个名为
stb\u Swap\u Tabu的
StringBuilder
用于存储课程名称, 我正在使用以下方法查找课程:

stb_Swap_Tabu.ToString.Contains("CourseName")
就我而言,性能是最重要的问题。
有没有更快的方法?

StringBuilder并不是真的用于所有字符串目的。如果您真的需要搜索一个,您必须编写自己的方法

有几种适合不同情况的字符串搜索算法

下面是Knuth–Morris–Pratt算法的一个简单实现,该算法只关心顺序匹配(没有大小写折叠,没有与区域性相关的排序,只是简单的码点到码点匹配)。它有一些初始的
Θ(m)
开销,其中
m
是所查找单词的长度,然后在
Θ(n)
中查找,其中
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;
  }
}
公共静态类StringBuilderSearching
{
公共静态布尔包含(此StringBuilder草垛、字符串指针)
{
返回草垛。索引(针)!=-1;
}
公共静态int IndexOf(此StringBuilder haystack,字符串指针)
{
如果(草堆==null | |针==null)
抛出新ArgumentNullException();
如果(指针长度==0)
返回0;//到处都是空字符串!
if(needle.Length==1)//不能仅仅通过旋转来实现
{
字符c=针[0];
for(intidx=0;idx!=haystack.Length;++idx)
if(haystack[idx]==c)
返回idx;
返回-1;
}
int m=0;
int i=0;
int[]T=KMPTable(针);
而(m+i-1?T[i]:0;
}
}
返回-1;
}      
私有静态int[]KMPTable(寻找字符串)
{
int[]表=新的int[sequed.Length];
int pos=2;
int cnd=0;
表[0]=-1;
表[1]=0;
while(位置<表格长度)
如果(被搜索[pos-1]==被搜索[cnd])
表[pos++]=++cnd;
否则,如果(cnd>0)
cnd=表[cnd];
其他的
表[pos++]=0;
返回表;
}
}

我知道这是一个老问题,但当我试图为自己的项目创建解决方案时,它出现在我的搜索结果中。我以为我需要搜索
StringBuilder.ToString
的方法结果,但后来我意识到我可以在
StringBuilder
本身上调用方法。我的情况可能与你的不一样,但我想我会分享:

Private函数valueFormatter(ByVal值作为字符串)作为字符串
'这将更正任何格式,使该值对CSV格式有效
'
“1)任何值,作为一个,在它里面,那么它必须被包装在一个“即,你好,世界->你好,世界”
“2)为了在值中转义一个”,请添加一个“即Hello”世界->Hello”世界
“3)如果该值中包含一个”,则它还必须包装为一个“即“Hello World”->“Hello World”->“Hello World”->“Hello World”
' 
“不,太好了
' " -> """"
' "" -> """"""
如果value.Contains(“,”)或value.Contains(“”),则
将某人调整为新的StringBuilder(值)
如果value.Contains(“”),则sb.Replace(“”,“”)
sb.插入(0,“”)。追加(“”)
使某人恢复原状
其他的
返回值
如果结束
端函数

如果您需要使用
StringBuilder
,那么您可能需要在每次搜索时调用
ToString
,这在性能方面不是一个好主意。
StringBuilder
用于构建字符串;假设您正在构建字符串,那么您已经拥有了组成部分;为什么不在t中搜索呢直接连接组成部分?
StringBuilder
可能是最不适合存储可搜索名称列表的数据类型。为什么不使用
列表
,并使用
列表
包含
方法?你有没有这个字符串的实际示例?你说它存储“课程名称”“-无论“课程”是否真正意味着“课程”,“名称”表示不止一个名称-因此,这可能是一个带分隔符的字符串。在这种情况下,将其切换到单个名称的
列表
哈希集
,对于较大数量的字符串,
列表
对于较小的字符串,将非常有意义。我同意这不太可能是这里需要的。尽管如此,在StringBuilder中查找子字符串还是会出现。正如@JonHanna提到的,我有一个很好的理由拥有一个生成器,这就是为什么我的问题标题是:StringBuilder中最快的搜索方法。根据我的测试结果,@JonHanna经过一些修改后给出的答案比使用
Conatins
要好28%。我将尝试制作抽象代码并在这里共享。StringBuilder有一个
Replace
函数,它必须不可避免地搜索字符串,甚至需要开始和结束索引,但没有提供
indexOf
函数,这是没有意义的。为什么我们要重做已经做过的事情呢?对于我来说,这个代码失败了,haystack“abcde”和needle“cd”,它返回false。它不应该是
返回m,不是
返回m==针的长度-1:m?@JuriRobl该位与未找到的.NET约定-1匹配。我不知道是什么导致了这次失败,如果有机会,我会稍后再看。