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

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


当前回答

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

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

阅读此处使用的数据结构: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;
  }
}

其他回答

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

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

阅读此处使用的数据结构: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;
  }
}

使用std::string::find如下所示:

if (s1.find(s2) != std::string::npos) {
    std::cout << "found!" << '\n';
}

注意:如果s2是s1的子字符串,则打印"found!", s1和s2都是std::string类型。

如果字符串的大小相对较大(数百字节或更多),并且c++17可用,您可能需要使用Boyer-Moore-Horspool搜索器(示例来自cppreference.com):

#include <iostream>
#include <string>
#include <algorithm>
#include <functional>

int main()
{
    std::string in = "Lorem ipsum dolor sit amet, consectetur adipiscing elit,"
                     " sed do eiusmod tempor incididunt ut labore et dolore magna aliqua";
    std::string needle = "pisci";
    auto it = std::search(in.begin(), in.end(),
                   std::boyer_moore_searcher(
                       needle.begin(), needle.end()));
    if(it != in.end())
        std::cout << "The string " << needle << " found at offset "
                  << it - in.begin() << '\n';
    else
        std::cout << "The string " << needle << " not found\n";
}

你可以尝试使用find函数:

string str ("There are two needles in this haystack.");
string str2 ("needle");

if (str.find(str2) != string::npos) {
//.. found.
} 

实际上,你可以尝试使用boost库,我认为std::string没有提供足够的方法来做所有常见的字符串操作。在boost中,你可以只使用boost::algorithm::包含:

#include <string>
#include <boost/algorithm/string.hpp>

int main() {
    std::string s("gengjiawen");
    std::string t("geng");
    bool b = boost::algorithm::contains(s, t);
    std::cout << b << std::endl;
    return 0;
}