简体   繁体   English

检查字符串是否包含 C++ 中的字符串

[英]Check if a string contains a string in C++

I have a variable of type std::string .我有一个std::string类型的变量。 I want to check if it contains a certain std::string .我想检查它是否包含某个std::string How would I do that?我该怎么做?

Is there a function that returns true if the string is found, and false if it isn't?是否有一个函数在找到字符串时返回真,如果没有找到则返回假?

Usestd::string::find as follows:使用std::string::find如下:

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

Note: "found!"注:“找到了!” will be printed if s2 is a substring of s1 , both s1 and s2 are of type std::string .如果s2s1的子字符串,则将打印, s1s2都是std::string类型。

You can try using thefind function:您可以尝试使用find功能:

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

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

Actually, you can try to use boost library,I think std::string doesn't supply enough method to do all the common string operation.In boost,you can just use the boost::algorithm::contains :实际上,您可以尝试使用 boost 库,我认为 std::string 没有提供足够的方法来执行所有常见的字符串操作。在 boost 中,您可以只使用boost::algorithm::contains

#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;
}

Starting from C++23 you can use std::string::contains从 C++23 开始,您可以使用std::string::contains

#include <string>

const auto haystack = std::string("haystack with needles");
const auto needle = std::string("needle");

if (haystack.contains(needle))
{
    // found!
}

You can try this你可以试试这个

string s1 = "Hello";
string s2 = "el";
if(strstr(s1.c_str(),s2.c_str()))
{
   cout << " S1 Contains S2";
}

In the event if the functionality is critical to your system, it is actually beneficial to use an old strstr method.如果该功能对您的系统至关重要,那么使用旧的strstr方法实际上是有益的。 The std::search method within algorithm is the slowest possible. algorithmstd::search方法是最慢的。 My guess would be that it takes a lot of time to create those iterators.我的猜测是创建这些迭代器需要很多时间。

The code that i used to time the whole thing is我用来计时的代码是

#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;
}

Here i generate random haystacks and search in them the needle .在这里,我产生随机haystacks ,并在他们的搜索needle The haystack count is set, but the length of strings within each haystack is increased from 10 in the beginning to 10240 in the end.设置了haystack数,但是每个haystack内的字符串长度从开始的10个增加到最后的10240个。 Most of the time the program spends actually generating random strings, but that is to be expected.大部分时间该程序实际上花费在生成随机字符串上,但这是意料之中的。

The output is:输出是:

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.

If the size of strings is relatively big (hundreds of bytes or more) and c++17 is available, you might want to use Boyer-Moore-Horspool searcher (example from cppreference.com):如果字符串的大小相对较大(数百字节或更多)并且 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";
}

If you don't want to use standard library functions, below is one solution.如果您不想使用标准库函数,以下是一种解决方案。

#include <iostream>
#include <string>

bool CheckSubstring(std::string firstString, std::string secondString){
    if(secondString.size() > firstString.size())
        return false;

    for (int i = 0; i < firstString.size(); i++){
        int j = 0;
        // If the first characters match
        if(firstString[i] == secondString[j]){
            int k = i;
            while (firstString[i] == secondString[j] && j < secondString.size()){
                j++;
                i++;
            }
            if (j == secondString.size())
                return true;
            else // Re-initialize i to its original value
                i = k;
        }
    }
    return false;
}

int main(){
    std::string firstString, secondString;

    std::cout << "Enter first string:";
    std::getline(std::cin, firstString);

    std::cout << "Enter second string:";
    std::getline(std::cin, secondString);

    if(CheckSubstring(firstString, secondString))
        std::cout << "Second string is a substring of the frist string.\n";
    else
        std::cout << "Second string is not a substring of the first string.\n";

    return 0;
}
#include <algorithm>        // std::search
#include <string>
using std::search; using std::count; using std::string;

int main() {
    string mystring = "The needle in the haystack";
    string str = "needle";
    string::const_iterator it;
    it = search(mystring.begin(), mystring.end(), 
                str.begin(), str.end()) != mystring.end();

    // if string is found... returns iterator to str's first element in mystring
    // if string is not found... returns iterator to mystring.end()

if (it != mystring.end())
    // string is found
else
    // not found

return 0;
}

From so many answers in this website I didn't find out a clear answer so in 5-10 minutes I figured it out the answer myself.从这个网站上的这么多答案中,我没有找到明确的答案,所以在 5-10 分钟内我自己找到了答案。 But this can be done in two cases:但这可以在两种情况下完成:

  1. Either you KNOW the position of the sub-string you search for in the string要么你知道你在字符串中搜索的子字符串的位置
  2. Either you don't know the position and search for it, char by char...要么你不知道位置并搜索它,一个字符一个字符......

So, let's assume we search for the substring "cd" in the string "abcde", and we use the simplest substr built-in function in C++所以,假设我们在字符串“abcde”中搜索子字符串“cd”,我们使用C++中最简单的substr内置函数

for 1:对于 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;
}

for 2: 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;
}

This is a simple function这是一个简单的函数

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;
}

You can also use the System namespace.您还可以使用 System 命名空间。 Then you can use the contains method.然后你可以使用 contains 方法。

#include <iostream>
using namespace System;

int main(){
    String ^ wholeString = "My name is Malindu";

    if(wholeString->ToLower()->Contains("malindu")){
        std::cout<<"Found";
    }
    else{
        std::cout<<"Not Found";
    }
}

Good to use std::regex_search also.也可以使用std::regex_search Stepping stone for making the search more generic.使搜索更通用的垫脚石。 Below is an example with comments.下面是一个带有注释的示例。

//THE STRING IN WHICH THE SUBSTRING TO BE FOUND.
std::string testString = "Find Something In This Test String";

//THE SUBSTRING TO BE FOUND.
auto pattern{ "In This Test" };

//std::regex_constants::icase - TO IGNORE CASE.
auto rx = std::regex{ pattern,std::regex_constants::icase };

//SEARCH THE STRING.
bool isStrExists = std::regex_search(testString, rx);

Need to include #include <regex>需要包含#include <regex>

For some reason, suppose the input string is observed something like "Find Something In This Example String", and interested to search either "In This Test" or "In This Example" then the search can be enhanced by simply adjusting the pattern as shown below.出于某种原因,假设观察到输入字符串类似于“在此示例字符串中查找内容”,并且有兴趣搜索“在此测试中”或“在此示例中”,则可以通过简单地调整模式来增强搜索,如图所示以下。

//THE SUBSTRING TO BE FOUND.
auto pattern{ "In This (Test|Example)" };

Note: I know that the question requires a function, which means the user is trying to find something simpler.注意:我知道这个问题需要一个函数,这意味着用户试图找到更简单的东西。 But still I post it in case anyone finds it useful.但我仍然发布它以防万一有人觉得它有用。

Approach using a Suffix Automaton.使用后缀自动机的方法。 It accepts a string (haystack), and after that you can input hundreds of thousands of queries (needles) and the response will be very fast, even if the haystack and/or needles are very long strings.它接受一个字符串(haystack),之后你可以输入数十万个查询(needles)并且响应会非常快,即使haystack和/或needles是很长的字符串。

Read about the data structure being used here: https://en.wikipedia.org/wiki/Suffix_automaton阅读此处使用的数据结构: 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;
  }
}

We can use this method instead.我们可以改用这个方法。 Just an example from my projects.只是我项目中的一个例子。 Refer the code.参考代码。 Some extras are also included.一些额外的东西也包括在内。

Look to the if statements!看看 if 语句!

/*
Every C++ program should have an entry point. Usually, this is the main function.
Every C++ Statement ends with a ';' (semi-colon)
But, pre-processor statements do not have ';'s at end.
Also, every console program can be ended using "cin.get();" statement, so that the console won't exit instantly.
*/

#include <string>
#include <bits/stdc++.h> //Can Use instead of iostream. Also should be included to use the transform function.

using namespace std;
int main(){ //The main function. This runs first in every program.

    string input;

    while(input!="exit"){
        cin>>input;
        transform(input.begin(),input.end(),input.begin(),::tolower); //Converts to lowercase.

        if(input.find("name") != std::string::npos){ //Gets a boolean value regarding the availability of the said text.
            cout<<"My Name is AI \n";
        }

        if(input.find("age") != std::string::npos){
            cout<<"My Age is 2 minutes \n";
        }
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C++ 检查字符串是否包含数字和。 只有[关闭] - C++ check if a string contains numbers and . only [closed] 如何检查字符串是否包含标点符号 - How to check if a string contains punctuation c++ 如何检查字符串是否包含字符或数字 C++ 和 C# - How to check if a string contains characters or numbers C++ and C# 有没有一种方法可以检查字符串是否在C ++中包含Unicode字符 - Is there a way to check whether a string contains unicode characters in C++ 如何检查给定的c ++字符串或char *是否只包含数字? - how to check if given c++ string or char* contains only digits? C++ 中的模板化 is_in() 函数(检查数组是否包含字符串) - Templated is_in() function (check if array contains string) in C++ c++ 为向量中的每个字符串检查它是否包含 substring - c++ for every string in vector check if it contains a substring C ++检查字符串是否至少包含1位数字和1个字母 - C++ Check if String contains atleast 1 digit and 1 letter 如何检查网站是否包含C ++中的字符串? - How do I check if a website contains a string in c++? C ++检查字符串是否包含字符以及如何将二进制字符串转换为整数 - c++ check if string contains a character or not and how to convert a binary string into integer
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM