查找给定字符串中的所有子串c++

ycl3bljg  于 2022-11-27  发布在  其他
关注(0)|答案(2)|浏览(136)

我遇到了一个问题,一个程序在一个给定的字符串中查找所有的子字符串。我试图使变量“found”,它将包含一个位置,一个先前找到的子字符串,然后开始搜索的位置。下面是我的代码:

#include <iostream>
#include <string>
  
using namespace std;
  
int main()
{
    string str;
    string str1;

    cin >> str >> str1;
    int i = 0;
    int found = -1;
    while(found < str1.size()){
        found = str1.find(str, found + 1);
        cout<<str1.find(str, found)<<endl;
        i++;
    }
}

用于以下输入:“abaabb”它什么都不打印。你能帮忙吗?

kx5bkwkv

kx5bkwkv1#

所以先讲一点理论:
substr(a,b)-〉返回从位置a到位置B剪切的字符串
find(a)-〉返回找到的字符或字符集“a”的位置。如果未找到,则返回-1。
让我们检查一下您的代码:

#include <iostream>
#include <string> //not really needed here. string should already be usable
  
using namespace std; //in small programs is ok but with big programs this could lead to problems with using specific things that could have the same names in std and other library. So its best to avoid this and or any other using namespace you use.
  
int main()
{
    string str; // you should really name your variables better
    string str1;

    cin >> str >> str1; // your variable names are unreadable at first glance
    int i = 0; // iterator cool but why is it needed if you're just using find()
    int found = -1; // good variable although the name "pos" would probably be better as to further explain to the programmer what the variable does
    while(found < str1.size()){ //not really sure what you were going for here
        found = str1.find(str, found + 1); // this could have been your while logic above instead
        cout<<str1.find(str, found)<<endl; // this finds the exact same position again using more resources. your variable found stores the position so doing cout << found << here would be better
        i++; 
    }
}

现在,让我们看看为什么您的代码在控制台上没有显示任何内容:

#include <iostream>
#include <string>
  
using namespace std;
  
int main()
{
    string str;
    string str1;

    cin >> str >> str1; //you input ab as str and abbb as str1
    int i = 0;
    int found = -1;
    while(found < str1.size()){ //first iteration is while(-1 < 4)
        found = str1.find(str, found + 1); //<-- find needs just 1 parameter. heres your problem
        cout<<str1.find(str, found)<<endl;
        i++;
    }
}

str 1.查找(“ab);- 〉函数find在字符串str 1中搜索“ab”。你不需要添加它要搜索的位置。另外,你的while循环依赖于found〈str1.size(),而与你的迭代器无关,这意味着你的循环将永远继续下去。每当这种情况发生时,大多数IDE都会崩溃,你的程序什么也不给你。
修复:

#include <iostream>

using namespace std;

int main()
{
    string str;
    string str1;
    int pos;
    cin >> str >> str1;
    for(int i = 0; i < str1.size(); i++) // this or could be while(true)
    {
        pos = str1.substr(i).find(str); //finds your string in the rest of the line
        if (pos == -1)
        {
            //NOT FOUND
            break; //stops
        }
        else
        {
            //FOUND
            cout << pos + i << endl; //pos is position in the cut out after adding i we get global position
            i += pos; // skip characters after we found them to NOT be found again
        }
    }
}
zpf6vheq

zpf6vheq2#

另一种可能的解决方案是:

  • 遍历输入字符串,直到您知道子字符串不再适合的点。
  • 对于每个输入字符串位置,检查每个子字符串是否以子字符串开头(自C++20起仅限starts_with)。

Demo(https://godbolt.org/z/nEnrh5Ehb)

#include <iostream>
#include <string>

int main() {
    std::string str{ "ab aab" };
    std::string sub{ "ab" };
    int count{};
    size_t last_index{ str.size() > sub.size() ? str.size() - sub.size() : 0 };
    for (size_t i{0}; i <= last_index; ++i) {
        if (str.substr(i).starts_with(sub)) {
            count++;
        }
    }
    std::cout << count;
}

// Outputs: 2

相关问题