C# - Поиск всех индексов подстроки
РЕДАКТИРОВАТЬ: Таким образом, получается, что то, что у меня было раньше, было правильно, я просто неправильно подсчитывал индексы. Спасибо за ваш вклад, хотя.
Работа над методом, который находит все индексы подстроки в данной строке от пользователя. У меня проблемы с получением правильных позиций из userString.IndexOf. Я знаю, что он находит все вхождения подстроки, но целочисленный индекс отключен на значительную величину.
private static void getSubStringPositions(string userString, string userSubString)
{
string subStringPositions = "";
int position = 0;
if (userString.IndexOf(userSubString, position) == -1)
{
Console.WriteLine("Your sub-string was not found in your string.\n");
return;
}
while (position < userString.Length)
{
position += userString.IndexOf(userSubString, position);
subStringPositions += Convert.ToString(position) + ", ";
}
Console.WriteLine("The occurernce(s) for your sub-string are: " + subStringPositions + "\n\n");
return;
}
Я думаю, что это может быть проблема с position += userString.IndexOf(userSubString, position);
но я не совсем уверен, как бы я мог установить новую начальную позицию, сохраняя при этом точную запись местоположений подстроки.
3 ответа
Снимите += перед позицией
position = userString.IndexOf(userSubString, position);
Также вы должны изменить свой код, чтобы сохранить начальную найденную позицию и установить переменную позиции для поиска после предыдущей
// Initial check...
position = userString.IndexOf(userSubString);
if(position == -1)
{
Console.WriteLine("Your sub-string was not found in your string.\n");
return;
}
// Save the found position and enter the loop
subStringPositions = Convert.ToString(position) + ", ";
while (position < userString.Length)
{
// Search restart from the character after the previous found substring
position = userString.IndexOf(userSubString, position + 1);
subStringPositions += Convert.ToString(position) + ", ";
}
И последнее замечание: если этот поиск дает много совпадений, лучше изменить конкатенацию строк, используя экземпляр класса StringBuilder.
StringBuilder subStringPositions = new StringBuilder();
subStringPositions.Append(Convert.ToString(position) + ", ");
while (position < userString.Length)
{
// Search restart from the character after the previous found substring
position = userString.IndexOf(userSubString, position + 1);
subStringPositions.Append(Convert.ToString(position) + ", ";
}
Console.WriteLine("The occurrence(s) for your sub-string are: " +
subStringPositions.ToString() + "\n\n");
Краткий способ найти эти индексы с помощью LINQ:
public static IEnumerable<int> FindIndexes(string text, string query)
{
return Enumerable.Range(0, text.Length - query.Length)
.Where(i => query.Equals(text.Substring(i, query.Length));
}
FindIndexes("abcbcbc", "bcb")
найдет вам индексы 1
а также 3
,
У вас есть другая проблема здесь. Допустим, вы звоните:
getSubStringPositions ("abcabcabcabc", "abcabc");
Ваша функция неправильно сообщит, что строка встречается дважды, тогда как на самом деле подстрока встречается 3 раза, например:
- abcabc.abcabc
- abc.abcabc.abc <- ваша функция перепрыгивает через эту
- abcabc.abcabc.