Поиск шаблона в строке

#c

#c

Вопрос:

Я создал вызываемый метод findPattern , который будет считывать строку и проверять, существует ли другая строка в первой.

Пример:

строка s1 = «abcdxbc»; шаблон строки = «bc»;

Метод проверит, существует ли «bc» в string s1 и выведет начальный индекс каждого вхождения шаблона «bc» внутри s1 .

Вот как вызывается метод:

 string s1 = "abcdxbc";
string pattern = "bc";

findPattern(string s1,string pattern);
  

В настоящее время мой метод может найти шаблон только в 1 строке, но я хочу, чтобы он проверял 2 строки.

Вот как он будет вызываться: findPattern(string s1, string s2, string pattern);

Пожалуйста, помогите

Спасибо

Код метода findPattern:

 void findPattern(string s1, string pattern)
{
   int s1Len = s1.length();
   int pLen = pattern.length();
   
   //for loop to move along the string s1
   for (int i = 0; i <= s1Len - pLen; i  )
   {
       int j = 0;
       while(j < pLen amp;amp; s1[i   j] == pattern[j]) //check that each char in pattern matches the char in s1
       {
            j  ;
       }
       
       //if pattern is found inside s1
       if(j == pLen) cout << i << " ";
   }
}

  

Комментарии:

1. То, что вы ищете, — это «переменные аргументы»

2. И то, что вы пытаетесь сделать, уже реализовано в Стандарте. Поиск std::find или std::find_first_of

3. вызовите find снова с новым начальным итератором

4. Если вам нужны все индексы needle , вы можете делать что-то вроде lastIndex = std::find(string, lastIndex) в цикле, пока больше ничего не будет найдено.

5. Почему бы просто не вызвать функцию 2-й раз для 2-й строки?

Ответ №1:

Продолжая ваш комментарий к std::basic_string::find находит только первое вхождение, которое игнорирует возвращаемое значение и size_type pos параметр, взятый в качестве его второго аргумента. Чтобы найти все подстроки, вы просто сохраняете количество возвращаемых символов и добавляете это плюс длину подстроки вместе, чтобы использовать в качестве следующей позиции для поиска, например

 void findPattern (const std::stringamp; s, const std::stringamp; sub)
{
    size_t  pos = 0,
            nchars = 0;
    
    while ((nchars = s.find(sub, pos)) != std::string::npos) {      /* find sub */
        std::cout << sub << " at: " << nchars << 'n';              /* output result */
        pos = nchars   sub.length();                                /* update pos */
    }
}
  

Объединив это с циклом, который вызывает функцию для каждой из строк "abcdxbc" , и "abcabcb" , вы могли бы сделать:

 #include <iostream>
#include <string>

void findPattern (const std::stringamp; s, const std::stringamp; sub)
{
    size_t  pos = 0,
            nchars = 0;
    
    while ((nchars = s.find(sub, pos)) != std::string::npos) {      /* find sub */
        std::cout << sub << " at: " << nchars << 'n';              /* output result */
        pos = nchars   sub.length();                                /* update pos */
    }
}

int main (void) {
    
    std::string str[] ={ {"abcdxbc"}, {"abcabcb"} },            /* array of strings */
                sub {"bc"};                                     /* substring to find */
    
    for (auto iter = str; iter != str   2; iter  ) {            /* loop over strings */
        std::cout << "nchecking for: '" << sub << "' in '" << *iter << "'nn";
        findPattern (*iter, sub);                               /* locate substrings */
    }
}
  

Пример использования / вывода

 $ ./bin/findallsubs

checking for: 'bc' in 'abcdxbc'

bc at: 1
bc at: 5

checking for: 'bc' in 'abcabcb'

bc at: 1
bc at: 4
  

Вы можете изменить выходные данные в соответствии с вашими потребностями.

Все std::string.find , .find_first_of , .find_first_not_of , … работают одинаково. Дайте мне знать, если у вас возникнут дополнительные вопросы.