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.
Другие вопросы по тегам