Как мне найти шаблон в строке? - PullRequest
0 голосов
/ 20 октября 2018

Итак, представьте, что у вас есть такая строка

o7o7o7o7o7o

Существует четкая схема o7o Мой подход заключался в том, чтобы найти второй o после первого, и это будет образец,и затем посмотрите, соответствует ли оно.

строка: как мне получить индекс второго o?

Я пробовал это

var pattern = "o7o7o7o7o7o";
var index = input.IndexOf("*");

Но это, очевидно, собирается получить первый индекс первого найденного o, я хочу получить второй.Как мне это сделать?

Ответы [ 4 ]

0 голосов
/ 20 октября 2018

Чтобы получить индекс второго вхождения o, когда между ними должно быть хотя бы 1 раз, а не o, вы можете использовать регулярное выражение с использованием группы захвата и получить индекс этой группы:

^[^o]*o[^o]+(o)

Это будет соответствовать:

  • ^ Утверждение начала строки
  • [^o]* Соответствие 0+ раз не o использование отрицательного класса символов
  • o Соответствие буквально
  • [^o]+ Соответствие 1+ раз, а не o использование отрицательного класса символов (используйте [^o]*, если есть возможностьтакже будет 2 подряд).
  • (o) Захват o в группе

Regex demo

string pattern = @"^[^o]*o[^o]+(o)";
string input = @"o7o7o7o7o7o";

Match m = Regex.Match(input, pattern);
Console.WriteLine(m.Groups[1].Index); // 2

Демо c #

0 голосов
/ 20 октября 2018

Также можно использовать Regex следующим образом:

var pattern = "o7o7o7o7o7o";

var regex = new Regex("7(o)");

var matches = regex.Matches(pattern);

foreach (Match match in matches)
{
    Console.WriteLine(match.Groups[1].Index);
}
0 голосов
/ 20 октября 2018

Построить префиксную функцию и искать сжатое представление как , описанное здесь

При заданной строке s длины n.Мы хотим найти самое короткое «сжатое» представление строки, то есть мы хотим найти строку t наименьшей длины, такую, чтобы s можно было представить как объединение одной или нескольких копий t.

Понятно, что нам нужно только найти длину т.Зная длину, ответом на проблему будет префикс s с этой длиной.

Давайте вычислим функцию префикса для s.Используя его последнее значение, мы определяем значение k = n − π [n − 1].Мы покажем, что если k делит n, то k будет ответом, иначе эффективное сжатие не существует и ответ будет n.

Но ваша строка не может быть представлена ​​как (u) ^ w, потому что у него есть чрезмерный символ в конце.В этом случае проверьте делимость (i+1) (i - индекс) на (i-p[i])

. Для s = '1231231231' мы можем получить представление (123)^3+1, потому что последний (i+1), делимый на k[i]=3, равен 9 * 1021.*

  i+1: p[i] k[i]
  1 : 0  1 
  2 : 0  2 
  3 : 0  3 
  4 : 1  3 
  5 : 2  3 
  6 : 3  3 
  7 : 4  3 
  8 : 5  3 
  9 : 6  3 
  10 : 7  3 
0 голосов
/ 20 октября 2018

Вы можете сделать это многими способами, самый быстрый способ будет цикл :

string pattern = "o7o7o7o7o7o";
int count = 0;
int index = 0;
while(index < pattern.Length)
{
     if(pattern[index] == 'o') count++;
     if(count == 2) break;
     index++;
}

и index - это то, что вы хотите.

Linq:

int index = pattern.Select((x, i) => new { x, i })
              .Where(a => a.x == 'o').Skip(1)
              .FirstOrDefault().i;

string.IndexOf ():

int count = 0, index = 0;
do
{
    index = pattern.IndexOf('o', index);
    if (index != -1) { count++; index++; }
} while (index != -1 && count < 2);

и есть много других способов, но я думаю, что три вышепримеры были бы хорошими, поскольку другие способы, о которых я думаю, медленнее (по крайней мере, те, о которых я могу думать).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...