我有一个std::string类型的变量。我想检查它是否包含一个特定的std::字符串。我该怎么做呢?

是否有一个函数,如果找到字符串返回true,如果没有找到则返回false ?


当前回答

这是一个简单的函数

bool find(string line, string sWord)
{
    bool flag = false;
    int index = 0, i, helper = 0;
    for (i = 0; i < line.size(); i++)
    {
        if (sWord.at(index) == line.at(i))
        {
            if (flag == false)
            {
                flag = true;
                helper = i;
            }
            index++;
        }
        else
        {
            flag = false;
            index = 0;
        }
        if (index == sWord.size())
        {
            break;
        }
    }
    if ((i+1-helper) == index)
    {
        return true;
    }
    return false;
}

其他回答

是什么

string response = "hello world";
string findMe = "world";

if(response.find(findMe) != string::npos)
{
     //found
}

这是一个简单的函数

bool find(string line, string sWord)
{
    bool flag = false;
    int index = 0, i, helper = 0;
    for (i = 0; i < line.size(); i++)
    {
        if (sWord.at(index) == line.at(i))
        {
            if (flag == false)
            {
                flag = true;
                helper = i;
            }
            index++;
        }
        else
        {
            flag = false;
            index = 0;
        }
        if (index == sWord.size())
        {
            break;
        }
    }
    if ((i+1-helper) == index)
    {
        return true;
    }
    return false;
}

从这个网站上的这么多答案中,我没有找到一个明确的答案,所以在5-10分钟内我自己找到了答案。 但这可以在两种情况下实现:

要么你知道你在字符串中搜索的子字符串的位置 要么你不知道它的位置,然后逐字符搜索它……

所以,让我们假设我们在字符串“abcde”中搜索子字符串“cd”,我们使用c++中最简单的substr内置函数

1:

#include <iostream>
#include <string>

    using namespace std;
int i;

int main()
{
    string a = "abcde";
    string b = a.substr(2,2);    // 2 will be c. Why? because we start counting from 0 in a string, not from 1.

    cout << "substring of a is: " << b << endl;
    return 0;
}

2:

#include <iostream>
#include <string>

using namespace std;
int i;

int main()
{
    string a = "abcde";

    for (i=0;i<a.length(); i++)
    {
        if (a.substr(i,2) == "cd")
        {
        cout << "substring of a is: " << a.substr(i,2) << endl;    // i will iterate from 0 to 5 and will display the substring only when the condition is fullfilled 
        }
    }
    return 0;
}

注意:我知道这个问题需要一个函数,这意味着用户试图找到一些更简单的东西。但我还是把它贴出来,以防有人觉得有用。

使用后缀自动机的方法。它接受一个字符串(干草堆),然后你可以输入成千上万的查询(针),并且响应将非常快,即使干草堆和/或针是非常长的字符串。

阅读此处使用的数据结构:https://en.wikipedia.org/wiki/Suffix_automaton

#include <bits/stdc++.h>

using namespace std;

struct State {
  int len, link;
  map<char, int> next;
};

struct SuffixAutomaton {
  vector<State> st;
  int sz = 1, last = 0;

  SuffixAutomaton(string& s) {
    st.assign(s.size() * 2, State());
    st[0].len = 0;
    st[0].link = -1;
    for (char c : s) extend(c);
  }

  void extend(char c) {
    int cur = sz++, p = last;
    st[cur].len = st[last].len + 1;
    while (p != -1 && !st[p].next.count(c)) st[p].next[c] = cur, p = st[p].link;
    if (p == -1)
      st[cur].link = 0;
    else {
      int q = st[p].next[c];
      if (st[p].len + 1 == st[q].len)
        st[cur].link = q;
      else {
        int clone = sz++;
        st[clone].len = st[p].len + 1;
        st[clone].next = st[q].next;
        st[clone].link = st[q].link;
        while (p != -1 && st[p].next[c] == q) st[p].next[c] = clone, p = st[p].link;

        st[q].link = st[cur].link = clone;
      }
    }
    last = cur;
  }
};

bool is_substring(SuffixAutomaton& sa, string& query) {
  int curr = 0;

  for (char c : query)
    if (sa.st[curr].next.count(c))
      curr = sa.st[curr].next[c];
    else
      return false;

  return true;
}

// How to use:
// Execute the code
// Type the first string so the program reads it. This will be the string
// to search substrings on.
// After that, type a substring. When pressing enter you'll get the message showing the
// result. Continue typing substrings.
int main() {
  string S;
  cin >> S;

  SuffixAutomaton sa(S);

  string query;
  while (cin >> query) {
    cout << "is substring? -> " << is_substring(sa, query) << endl;
  }
}

如果该功能对您的系统至关重要,那么使用旧的strstr方法实际上是有益的。算法中的std::search方法是最慢的。我的猜测是,创建这些迭代器需要很多时间。

我用来计时的代码是

#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <random>
#include <chrono>

std::string randomString( size_t len );

int main(int argc, char* argv[])
{
        using namespace std::chrono;

        const size_t haystacksCount = 200000;
        std::string haystacks[haystacksCount];
        std::string needle = "hello";

        bool sink = true;

        high_resolution_clock::time_point start, end;
        duration<double> timespan;

        int sizes[10] = { 10, 20, 40, 80, 160, 320, 640, 1280, 5120, 10240 };

        for(int s=0; s<10; ++s)
        {
                std::cout << std::endl << "Generating " << haystacksCount << " random haystacks of size " << sizes[s] << std::endl;
                for(size_t i=0; i<haystacksCount; ++i)
                {
                        haystacks[i] = randomString(sizes[s]);
                }

                std::cout << "Starting std::string.find approach" << std::endl;
                start = high_resolution_clock::now();
                for(size_t i=0; i<haystacksCount; ++i)
                {
                        if(haystacks[i].find(needle) != std::string::npos)
                        {
                                sink = !sink; // useless action
                        }
                }
                end = high_resolution_clock::now();
                timespan = duration_cast<duration<double>>(end-start);
                std::cout << "Processing of " << haystacksCount << " elements took " << timespan.count() << " seconds." << std::endl;

                std::cout << "Starting strstr approach" << std::endl;
                start = high_resolution_clock::now();
                for(size_t i=0; i<haystacksCount; ++i)
                {
                        if(strstr(haystacks[i].c_str(), needle.c_str()))
                        {
                                sink = !sink; // useless action
                        }
                }
                end = high_resolution_clock::now();
                timespan = duration_cast<duration<double>>(end-start);
                std::cout << "Processing of " << haystacksCount << " elements took " << timespan.count() << " seconds." << std::endl;

                std::cout << "Starting std::search approach" << std::endl;
                start = high_resolution_clock::now();
                for(size_t i=0; i<haystacksCount; ++i)
                {
                        if(std::search(haystacks[i].begin(), haystacks[i].end(), needle.begin(), needle.end()) != haystacks[i].end())
                        {
                                sink = !sink; // useless action
                        }
                }
                end = high_resolution_clock::now();
                timespan = duration_cast<duration<double>>(end-start);
                std::cout << "Processing of " << haystacksCount << " elements took " << timespan.count() << " seconds." << std::endl;
        }

        return 0;
}

std::string randomString( size_t len)
{
        static const char charset[] = "abcdefghijklmnopqrstuvwxyz";
        static const int charsetLen = sizeof(charset) - 1;
        static std::default_random_engine rng(std::random_device{}());
        static std::uniform_int_distribution<> dist(0, charsetLen);
        auto randChar = [charset, &dist, &rng]() -> char
        {
                return charset[ dist(rng) ];
        };

        std::string result(len, 0);
        std::generate_n(result.begin(), len, randChar);
        return result;
}

在这里,我随机生成干草堆,并在其中搜索针。设置了草垛计数,但是每个草垛中的字符串长度从开始的10增加到最后的10240。程序大部分时间实际上是在生成随机字符串,但这是意料之中的。

输出结果为:

Generating 200000 random haystacks of size 10
Starting std::string.find approach
Processing of 200000 elements took 0.00358503 seconds.
Starting strstr approach
Processing of 200000 elements took 0.0022727 seconds.
Starting std::search approach
Processing of 200000 elements took 0.0346258 seconds.

Generating 200000 random haystacks of size 20
Starting std::string.find approach
Processing of 200000 elements took 0.00480959 seconds.
Starting strstr approach
Processing of 200000 elements took 0.00236199 seconds.
Starting std::search approach
Processing of 200000 elements took 0.0586416 seconds.

Generating 200000 random haystacks of size 40
Starting std::string.find approach
Processing of 200000 elements took 0.0082571 seconds.
Starting strstr approach
Processing of 200000 elements took 0.00341435 seconds.
Starting std::search approach
Processing of 200000 elements took 0.0952996 seconds.

Generating 200000 random haystacks of size 80
Starting std::string.find approach
Processing of 200000 elements took 0.0148288 seconds.
Starting strstr approach
Processing of 200000 elements took 0.00399263 seconds.
Starting std::search approach
Processing of 200000 elements took 0.175945 seconds.

Generating 200000 random haystacks of size 160
Starting std::string.find approach
Processing of 200000 elements took 0.0293496 seconds.
Starting strstr approach
Processing of 200000 elements took 0.00504251 seconds.
Starting std::search approach
Processing of 200000 elements took 0.343452 seconds.

Generating 200000 random haystacks of size 320
Starting std::string.find approach
Processing of 200000 elements took 0.0522893 seconds.
Starting strstr approach
Processing of 200000 elements took 0.00850485 seconds.
Starting std::search approach
Processing of 200000 elements took 0.64133 seconds.

Generating 200000 random haystacks of size 640
Starting std::string.find approach
Processing of 200000 elements took 0.102082 seconds.
Starting strstr approach
Processing of 200000 elements took 0.00925799 seconds.
Starting std::search approach
Processing of 200000 elements took 1.26321 seconds.

Generating 200000 random haystacks of size 1280
Starting std::string.find approach
Processing of 200000 elements took 0.208057 seconds.
Starting strstr approach
Processing of 200000 elements took 0.0105039 seconds.
Starting std::search approach
Processing of 200000 elements took 2.57404 seconds.

Generating 200000 random haystacks of size 5120
Starting std::string.find approach
Processing of 200000 elements took 0.798496 seconds.
Starting strstr approach
Processing of 200000 elements took 0.0137969 seconds.
Starting std::search approach
Processing of 200000 elements took 10.3573 seconds.

Generating 200000 random haystacks of size 10240
Starting std::string.find approach
Processing of 200000 elements took 1.58171 seconds.
Starting strstr approach
Processing of 200000 elements took 0.0143111 seconds.
Starting std::search approach
Processing of 200000 elements took 20.4163 seconds.