Например, пользователь вошел, "Я люблю это сообщение!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
последовательный дублирующийся восклицательный знак"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" должен быть обнаружен.
Следующее регулярное выражение обнаружит повторяющиеся символы. Вы можете увеличить количество или ограничить его определенными символами, чтобы сделать его более надежным.
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();
}
Вот быстрое решение, которое я придумал, добавив несколько дополнительных дубликатов на всякий случай. Как отмечали другие в комментариях, некоторые дубликаты будут полностью законными, поэтому вы можете сузить свои критерии до знаков препинания, а не простых символов.
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));
}
Вот и пример функции, которая ищет последовательность последовательных символов указанной длины, а также игнорирует символы пробелов:
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;
}
Исправьте ошибку фиксированного диапазона: /
Используйте 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
На мой взгляд, лучший способ - создать массив, каждый элемент в массиве отвечает за одну пару символов в строке рядом друг с другом, например, первый aa, bb, cc, dd. Эта конструкция массива с 0 для каждого элемента.
Решением этой проблемы является запрос для этой строки и обновление значений массива. Затем вы можете проанализировать этот массив на предмет того, что вам нужно.
Пример: для строки: bbaaaccccdab ваш массив результатов будет {2, 1, 3}, потому что 'aa' может найти 2 раза, 'bb' может найти один раз (в начале строки), 'cc' может найти три раза.
Почему «cc» три раза? Потому что 'cc'cc & c'cc'c & cc'cc'.
Можно легко выполнить в 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.
Вы можете легко расширить это, чтобы получить начальную позицию, я оставлю это вам.