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

我有一个类型为std::string的变量。我想检查它是否包含某个std::string。我该怎么做?

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

1218366 次浏览

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

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

注意:如果s2s1的子字符串,s1s2都是std::string类型,则将打印“找到!”。

您可以尝试使用find函数:

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


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

实际上,你可以尝试使用Boost库,我认为std::字符串没有提供足够的方法来完成所有常见的字符串操作。

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

你可以试试这个

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

如果你不想使用标准库函数,下面是一个解决方案。

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

这是一个简单的功能

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

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

  1. 要么你知道你在字符串中搜索的子字符串的位置
  2. 要么你不知道的位置和搜索它,char的char…

所以,假设我们在字符串“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;
}

您也可以使用System命名空间。 然后你可以使用包含方法。

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

我们可以使用这个方法。 这是我的项目中的一个例子。 引用代码。 还包括一些额外的内容。

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


}

如果功能对您的系统至关重要,实际上使用旧的strstr方法是有益的。algorithm中的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;
}

在这里,我生成随机haystacks并在其中搜索needle。设置了干草堆计数,但每个干草堆中的字符串长度从开始的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.

如果字符串的大小相对较大(数百字节或更多)并且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";
}

从C++23开始,您可以使用d::弦::c

#include <string>


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


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

使用std::regex_search也很好。使搜索更通用的垫脚石。下面是一个带有评论的示例。

//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);

需要包含#include <regex>

出于某种原因,假设观察到输入字符串类似于“在这个示例字符串中查找某些内容”,并且有兴趣搜索“在这个测试中”或“在这个示例中”,那么可以通过简单地调整模式来增强搜索,如下所示。

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

注意:我知道这个问题需要一个函数,这意味着用户试图找到更简单的东西。但我仍然发布它,以防有人发现它很有用。

使用后缀自动机的方法。它接受一个字符串(haystack),之后您可以输入数十万个查询(针),响应将非常快,即使haystack和/或针是非常长的字符串。

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


关于

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


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