Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在字符串中找到子字符串的所有位置?_C++_String_Find - Fatal编程技术网

C++ 如何在字符串中找到子字符串的所有位置?

C++ 如何在字符串中找到子字符串的所有位置?,c++,string,find,C++,String,Find,我想在一个大字符串中搜索字符串的所有位置。只需使用std::string::find(),它返回找到子字符串的位置,或者std::string::npos(如果没有找到) 是文档 以下是本文档中的示例: // string::find #include <iostream> #include <string> using namespace std; int main () { string str ("There are two needles in this h

我想在一个大字符串中搜索字符串的所有位置。

只需
使用std::string::find()
,它返回找到子字符串的位置,或者
std::string::npos
(如果没有找到)

是文档

以下是本文档中的示例:

// string::find
#include <iostream>
#include <string>
using namespace std;

int main ()
{
  string str ("There are two needles in this haystack with needles.");
  string str2 ("needle");
  size_t found;

  // different member versions of find in the same order as above:
  found=str.find(str2);
  if (found!=string::npos)
    cout << "first 'needle' found at: " << int(found) << endl;

  found=str.find("needles are small",found+1,6);
  if (found!=string::npos)
    cout << "second 'needle' found at: " << int(found) << endl;

  found=str.find("haystack");
  if (found!=string::npos)
    cout << "'haystack' also found at: " << int(found) << endl;

  found=str.find('.');
  if (found!=string::npos)
    cout << "Period found at: " << int(found) << endl;

  // let's replace the first needle:
  str.replace(str.find(str2),str2.length(),"preposition");
  cout << str << endl;

  return 0;
}
//字符串::查找
#包括
#包括
使用名称空间std;
int main()
{
string str(“这个有针的干草堆里有两根针。”);
字符串str2(“针”);
未找到尺寸;
//find的不同成员版本的顺序与上述相同:
found=str.find(str2);
如果(找到!=字符串::npos)

使用
std::string::find
可以执行以下操作:

std::string::size_type start_pos = 0;
while( std::string::npos != 
          ( start_pos = mystring.find( my_sub_string, start_pos ) ) )
{
    // do something with start_pos or store it in a container
    ++start_pos;
}
std::string::iterator it(str.begin()), end(str.end());
std::string::iterator s_it(search_str.begin()), s_end(search_str.end());

it = std::search(it, end, s_it, s_end);

while(it != end)
{
  // do something with this position..

  // a tiny optimisation could be to buffer the result of the std::distance - heyho..
  it = std::search(std::advance(it, std::distance(s_it, s_end)), end, s_it, s_end);
}


编辑:啊!谢谢你的评论,纳瓦兹!更好吗?

另外两个答案是正确的,但是它们非常慢,并且具有O(N^2)复杂度。但是有一种算法,它可以找到O(N)复杂度的所有子字符串

编辑:

此外,还有另一种算法:所谓的“Z函数”具有O(N)复杂度,但我找不到该算法的英文源(可能是因为还有另一种更著名的同名算法——Rieman的Z函数),所以我将把它的代码放在这里,并解释它的作用

void calc_z (string &s, vector<int> & z)
{
    int len = s.size();
    z.resize (len);

    int l = 0, r = 0;
    for (int i=1; i<len; ++i)
        if (z[i-l]+i <= r)
            z[i] = z[i-l];
        else
        {
            l = i;
            if (i > r) r = i;
            for (z[i] = r-i; r<len; ++r, ++z[i])
                if (s[r] != s[z[i]])
                    break;
            --r;
        }
}

int main()
{
    string main_string = "some string where we want to find substring or sub of string or just sub";
    string substring = "sub";
    string working_string = substring + main_string;
    vector<int> z;
    calc_z(working_string, z);

    //after this z[i] is maximal length of prefix of working_string
    //which is equal to string which starting from i-th position of
    //working_string. So the positions where z[i] >= substring.size()
    //are positions of substrings.

    for(int i = substring.size(); i < working_string.size(); ++i)
        if(z[i] >=substring.size())
            cout << i - substring.size() << endl; //to get position in main_string
}
void calc_z(字符串&s,向量&z)
{
int len=s.size();
z、 调整大小(len);
int l=0,r=0;
for(int i=1;i=substring.size())

cout为了完整起见,我将添加另一种方法,
std::search
,类似于
std::string::find
,不同之处在于使用迭代器,类似于:

std::string::size_type start_pos = 0;
while( std::string::npos != 
          ( start_pos = mystring.find( my_sub_string, start_pos ) ) )
{
    // do something with start_pos or store it in a container
    ++start_pos;
}
std::string::iterator it(str.begin()), end(str.end());
std::string::iterator s_it(search_str.begin()), s_end(search_str.end());

it = std::search(it, end, s_it, s_end);

while(it != end)
{
  // do something with this position..

  // a tiny optimisation could be to buffer the result of the std::distance - heyho..
  it = std::search(std::advance(it, std::distance(s_it, s_end)), end, s_it, s_end);
}

我发现这有时比
std::string::find
,特别是如果您将字符串表示为
向量

@sehe:linked文档中有一个(我现在已经重新编写了)(显然有点太晚了;)那更好。但是现在,你需要循环中的
if else
吗?哈,很好:)下面是我半睡时发生的事情:不,我不需要它。只是在第一次,我想如果没有它,我可能会错过最后一个字符,如果
我的sub\u字符串
只是一个字母,放在
mystring
的结尾。再次感谢!这看起来比之前更好…+1hmm,你不认为
std::string::find
的作者可能已经在下面实现了KMP吗?事实上,随着新SSE4.2指令的出现,这种优化可能已经在低级函数中可用除非你使用你自己的代码中的指令,否则你不太可能击败那些低级函数的性能。最终的结果是,除非你能证明经验是很慢的,不要重新发明……M2CU你可以测试你自己。让我们考虑MIN字符串=“A”(1000000次)+“B”+“A”。(1000000次)和子串=“A”(999999次)。使用STD::String::查找和@ KIIL KIROV的代码,您的程序将工作2-3天,但我的一个将返回Iddial.您可能还想考虑使用该算法,它是O(n),并且用较长的针(子串)执行得更好。当有两个参数决定运行时间时,用O(N)或O(N*N)来描述字符串查找算法是有点荒谬的,N_haystack和N_pine。当N_pine=1时,几乎所有算法都是O(N_haystack*N_pine)。大多数算法都是O(N_haystack*N_pine)或更好,你可以假设N_pine