Есть ли лучший путь, чем Строка. Замена для удаления клавиш Backspace из строки?

Возьмите привет и привет в качестве примера.

  1. Обе строки начинаются с одного и того же символа, если они удаляют его из обоих.

При этом hello и hlo уменьшаются до ello и lo

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

    1. Если запрос пустой, результатом является совпадение. Если строка пуста, но запрос нет, результат не совпадает.

    С этим по правилу 3 результат совпадает.

11
задан esac 4 May 2009 в 21:55
поделиться

8 ответов

Probably the easiest is to just iterate over the entire string. Given your inputs, the following code does the trick in 1-pass

public string ReplaceBackspace(string hasBackspace)
{
    if( string.IsNullOrEmpty(hasBackspace) )
        return hasBackspace;

    StringBuilder result = new StringBuilder(hasBackspace.Length);
    foreach (char c in hasBackspace)
    {
        if (c == '\b')
        {
            if (result.Length > 0)
                result.Length--;
        }
        else
        {
            result.Append(c);
        }
    }
    return result.ToString();
}
12
ответ дан 3 December 2019 в 04:14
поделиться

То, как я бы это сделал, - нехитрое, но простое для понимания.

Создайте набор символов. Затем переберите строку от начала до конца. Если символ является нормальным символом (без слеша), поместите его в стек. Если это косая черта, а следующий символ - «b», вытолкните вершину стека. Если стек пуст, игнорируйте его.

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

6
ответ дан 3 December 2019 в 04:14
поделиться

Версия регулярных выражений:

var data = @"patt\b\b\b\b\b\b\b\b\b\bfoo";
var regex = new Regex(@"(^|[^\\b])\\b");

while (regex.IsMatch(data))
{
    data = regex.Replace(data, "");
}

Оптимизированная версия (и эта работает с backspace '\ b', а не со строкой "\ b"):

var data = "patt\b\b\b\b\b\b\b\b\b\bfoo";
var regex = new Regex(@"[^\x08]\x08", RegexOptions.Compiled);

while (data.Contains('\b'))
{
    data = regex.Replace(data.TrimStart('\b'), "");
}
3
ответ дан 3 December 2019 в 04:14
поделиться
public static string ProcessBackspaces(string source)
{
    char[] buffer = new char[source.Length];
    int idx = 0;

    foreach (char c in source)
    {
        if (c != '\b')
        {
            buffer[idx] = c;
            idx++;
        }
        else if (idx > 0)
        {
            idx--;
        }
    }

    return new string(buffer, 0, idx);
}

РЕДАКТИРОВАТЬ

Я сделал быстрый грубый тест кода, размещенного в ответы до сих пор (обработка двух примеров строк из вопроса, миллион раз каждая):

 ANSWER                 | TIME (ms)
------------------------|-----------
 Luke (this one)        |       318
 Alexander Taran        |       567
 Robert Paulson         |       683
 Markus Nigbur          |      2100
 Kamarey (new version)  |      7075
 Kamarey (old version)  |     30902
3
ответ дан 3 December 2019 в 04:14
поделиться

я бы пошел так: код не проверен

char[] result = new char[input.Length()];
int r =0;
for (i=0; i<input.Length(); i++){
if (input[i] == '\b'  && r>0) r--;
 else result[r]=input[i];

}

string resultsring = result.take(r);
0
ответ дан 3 December 2019 в 04:14
поделиться

Создайте StringBuilder и скопируйте все, кроме символов возврата на одну позицию.

-1
ответ дан 3 December 2019 в 04:14
поделиться

Вы можете перебирать строку назад, создавая массив символов по мере продвижения. Каждый раз, когда вы нажимаете клавишу Backspace, увеличиваете счетчик, и каждый раз, когда вы нажимаете нормальный символ, пропускайте его, если ваш счетчик ненулевой, и уменьшайте счетчик.

Я не уверен, что лучшая структура данных C # предназначена для управляйте этим и затем сможете быстро получить строку в правильном порядке. StringBuilder имеет метод Insert , но я не знаю, будет ли он производительным, чтобы продолжать вставлять символы в начале или нет. Вы можете поместить символы в стек и нажать ToArray () в конце - это может быть или не быть быстрее.

2
ответ дан 3 December 2019 в 04:14
поделиться
String myString = "patt\b\b\b\b\b\b\b\b\b\bfoo";
      List<char> chars = myString.ToCharArray().ToList();
      int delCount = 0;

      for (int i = chars.Count -1; i >= 0; i--)
      {
        if (chars[i] == '\b')
        {
          delCount++;
          chars.RemoveAt(i);
        } else {
          if (delCount > 0 && chars[i] != null) {
            chars.RemoveAt(i);
            delCount--;
          }
        }
      }
0
ответ дан 3 December 2019 в 04:14
поделиться
Другие вопросы по тегам:

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