Что состоит в том, чтобы обнаружить самый эффективный путь, если строка содержит много последовательных дублирующихся символов в C#?

Например, пользователь вошел, "Я люблю это сообщение!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"

последовательный дублирующийся восклицательный знак"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" должен быть обнаружен.

8
задан silent 19 April 2010 в 22:49
поделиться

6 ответов

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

        int threshold = 3;
        string stringToMatch = "thisstringrepeatsss";
        string pattern = "(\\d)\\" + threshold + " + ";
        Regex r = new Regex(pattern);
        Match m = r.Match(stringToMatch);
        while(m.Success)
        {
                Console.WriteLine("character passes threshold " + m.ToString());
                m = m.NextMatch();
         }
3
ответ дан 5 December 2019 в 23:14
поделиться

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

string input = "I loove this post!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!aa";

int index = -1;
int count =1;
List<string> dupes = new List<string>();

for (int i = 0; i < input.Length-1; i++)
{
    if (input[i] == input[i + 1])
    {
        if (index == -1)
            index = i;

        count++;
    }
    else if (index > -1)
    {
        dupes.Add(input.Substring(index, count));
        index = -1;
        count = 1;
    }
}

if (index > -1)
{
    dupes.Add(input.Substring(index, count));
}
0
ответ дан 5 December 2019 в 23:14
поделиться

Вот и пример функции, которая ищет последовательность последовательных символов указанной длины, а также игнорирует символы пробелов:

    public static bool HasConsecutiveChars(string source, int sequenceLength)
    {
        if (string.IsNullOrEmpty(source))
            return false;
        if (source.Length == 1) 
            return false;

        int charCount = 1;
        for (int i = 0; i < source.Length - 1; i++)
        {
            char c = source[i];
            if (Char.IsWhiteSpace(c))
                continue;
            if (c == source[i+1])
            {
                charCount++;
                if (charCount >= sequenceLength)
                    return true;
            }
            else
                charCount = 1;
        }

        return false;
    }

Исправьте ошибку фиксированного диапазона: /

2
ответ дан 5 December 2019 в 23:14
поделиться

Используйте LINQ! (Для всего, не только этого)

string test = "aabb";
return test.Where((item, index) => index > 0 && item.Equals(test.ElementAt(index)));
// returns "abb", where each of these items has the previous letter before it

ИЛИ

string test = "aabb";
return test.Where((item, index) => index > 0 && item.Equals(test.ElementAt(index))).Any();
// returns true
0
ответ дан 5 December 2019 в 23:14
поделиться

На мой взгляд, лучший способ - создать массив, каждый элемент в массиве отвечает за одну пару символов в строке рядом друг с другом, например, первый aa, bb, cc, dd. Эта конструкция массива с 0 для каждого элемента.

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

Пример: для строки: bbaaaccccdab ваш массив результатов будет {2, 1, 3}, потому что 'aa' может найти 2 раза, 'bb' может найти один раз (в начале строки), 'cc' может найти три раза.

Почему «cc» три раза? Потому что 'cc'cc & c'cc'c & cc'cc'.

0
ответ дан 5 December 2019 в 23:14
поделиться

Можно легко выполнить в O (n) : для каждого символа, если предыдущий символ совпадает с текущим, увеличивайте временный счет. Если это не так, сбросьте временный счетчик. При необходимости обновляйте свой глобальный файл на каждом шаге.

Для abbccc вы получите:

a => temp = 1, global = 1
b => temp = 1, global = 1
b => temp = 2, global = 2
c => temp = 1, global = 2
c => temp = 2, global = 2
c => temp = 3, global = 3

=> c appears three times. Extend it to get the position, then you should be able to print the "ccc" substring.

Вы можете легко расширить это, чтобы получить начальную позицию, я оставлю это вам.

0
ответ дан 5 December 2019 в 23:14
поделиться
Другие вопросы по тегам:

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