Вопрос по vb.net, .net, performance, c#, stringbuilder – Самый быстрый метод поиска в StringBuilder

13

у меня естьStringBuilder названныйstb_Swap_Tabu используется для хранения курса "Имена, я использую следующий метод, чтобы найти курс:

stb_Swap_Tabu.ToString.Contains("CourseName")

в моем случае производительность является наиболее важной проблемой. Есть ли более быстрый способ?

Я согласенвряд ли будет то, чтоздесь нужно Тем не менее, поиск подстроки в StringBuilder подходит. Jon Hanna
У вас есть пример того, что эта строка на самом деле? Вы говорите, что магазины "Курс'Имена " - или нет "Курсы" на самом деле означает "Курсы""Имена» предлагает более одного имени - так что, предположительно, это строка с разделителями. В этом случае переключение наList или жеHashSet изиндивидуальный имена будут иметь много смысла Marc Gravell
Я неЯ думаю, что вы провели много собственных исследований для этого. Вы могли бы легко узнать, что StringBuilder неt подходит для этой цели, если необходимо учитывать производительность или эффективность. Shakti Prakash Singh
Если вам нужно использоватьStringBuilder затем вы'возможно, мне нужно будет позвонитьToString каждый раз, когда вы хотите искать, который неотличная идея с точки зрения производительности.StringBuilder используется длястроить строки; по-видимому, если выперестраивая струны, у вас уже есть составные части; почему Дон'вы ищете в этих составных частях непосредственно вместо этого? LukeH

Ваш Ответ

2   ответа
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
24

StringBuilder не былt действительно предназначен для всех строковых целей. Если вам действительно нужно искать один, вы должны написать свой собственный метод.

Существует несколько алгоритмов поиска строк, подходящих для разных случаев.

Ниже приведена простая реализация Knuth–Моррис-Алгоритм Пратта, который заботится только о порядковых соответствиях (без свертывания регистра, без сопоставления, связанного с культурой, просто простая комбинация кодовых точек и кодовых точек). Это имеет некоторые начальныеΘ(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;
  }
}
Это нене имеет смысла, что StringBuilder имеетReplace функция, которая неизбежно должна искать строку и даже принимает начальный и конечный индексы, но не обеспечиваетindexOf функция. Почему нам осталось переделать что?уже сделано? Slight
не должен»это будет простоreturn m;не?return m == needle.Length ? -1 : m; Juri Robl
@JuriRobl этот бит должен соответствовать соглашению .NET -1 для not found. Дон»не знаю чтоТем не менее, если я получу шанс, посмотрим позже. Jon Hanna
Этот код терпит неудачу для меня с стогом сена "ABCDE» и иголка "CD", он возвращает ложь. Juri Robl

Похожие вопросы