#c# #.net #algorithm
#c# #.net #алгоритм
Вопрос:
Я пытаюсь узнать, как извлечь все числа из строки, где число начинается со случайной цифры, которая находится в диапазоне от 0 до 9, а затем заканчивается той же самой, но если перед появлением следующей буквы есть еще одна такая цифра, она должна включать и эту.
Позвольте мне показать вам пример. Возьмем, к примеру, эту строку, 12346171par827here727next8number5052car
затем моя программа извлекла бы 12346171
, 727
, 505
И что у меня есть до сих пор, это то, что, очевидно, не делает того, что должно, но я не могу найти хороший алгоритм.
Как мне правильно извлечь числа?
string input = "12346171par827here727next8number5052car";
var charArray = input.ToArray();
int pos = 0;
var firstNum = 0;
var secondNum = 0;
for (int i = 0; i < charArray.Length; i )
{
if (char.IsDigit(charArray[i]))
{
firstNum = charArray[i];
for (int j = i; j < charArray.Length; j )
{
if (char.IsDigit(charArray[j]) amp;amp; charArray[j] == firstNum)
{
secondNum = charArray[j];
}
}
}
}
Комментарии:
1. Я не уверен, что понимаю вывод здесь, почему результат не включает
123461
и171
. Это ошибка, или это реальное поведение, которое вы хотите?
Ответ №1:
Простым способом добиться этого было бы использовать регулярные выражения. Вы можете использовать следующий шаблон регулярных выражений:
([0-9])[0-9]*1
Подробные сведения:
([0-9]) # Matches a single digit and put it in group #1.
[0-9]* # Matches zero or more digits.
1 # Matches the same string that was captured in group #1.
Вот полный пример:
string input = "12346171par827here727next8number5052car";
string pattern = @"([0-9])[0-9]*1";
var matches = Regex.Matches(input, pattern);
foreach (Match match in matches)
{
Console.WriteLine(match.Value);
}
Вывод:
12346171
727
505
Обратите внимание, что приведенный выше шаблон будет соответствовать «505» из «6505». Если вы хотите предотвратить это, убедившись, что повторяющаяся цифра находится в начале числа, вы можете использовать отрицательный взгляд назад. В этом случае шаблон будет:
(?<![0-9])([0-9])[0-9]*1
<a rel="noreferrer noopener nofollow" href="https:///regexstorm.net/tester?p=(?ДЕМОНСТРАЦИЯ.
Ответ №2:
Предполагая, что ваши правила правильно определены. Вы могли бы сделать это O (n) довольно эффективно с помощью старого доброго цикла for
Учитывая
public static IEnumerable<string> Get(string input)
{
int last = -1, first = -1;
for (var index = 0; index < input.Length; index )
if (!char.IsDigit(input[index]))
{
if (last > 1)
yield return input.Substring(first, last - first 1);
first = last = -1;
}
else if (first == -1)
first = index;
else if (input[first] == input[index])
last = index;
if (last > 1)
yield return input.Substring(first, last - first 1);
}
Использование
var input = "12346171par827here727next8number5052car";
Console.WriteLine(string.Join(", ", Get(input)));
Вывод
12346171, 727, 505