C++ 查找字符串是否包含C++;(允许增压)

C++ 查找字符串是否包含C++;(允许增压),c++,string,boost,C++,String,Boost,假设我有一个字符串,我想知道是否有一个特定的字符(比如“|”)存在,那么最好和最快的方法是什么?我知道字符串查找实现。我要求比这个更快的实现。使用 没有比这更有效的了。O(n)是你能做的最好的。标准库实现应该是非常优化的。只有一种方法可以做到这一点。只需在字符串上迭代以检查您正在查找的字符是否存在。您可以通过使用string::find函数来实现这一点,该函数获取一个字符并返回该字符在字符串中出现的第一个位置,如果该值不存在,则返回string::npos。您还可以使用std::find,它获取

假设我有一个字符串,我想知道是否有一个特定的字符(比如“|”)存在,那么最好和最快的方法是什么?我知道字符串查找实现。我要求比这个更快的实现。

使用


没有比这更有效的了。O(n)是你能做的最好的。标准库实现应该是非常优化的。

只有一种方法可以做到这一点。只需在字符串上迭代以检查您正在查找的字符是否存在。您可以通过使用
string::find
函数来实现这一点,该函数获取一个字符并返回该字符在字符串中出现的第一个位置,如果该值不存在,则返回
string::npos
。您还可以使用
std::find
,它获取两个迭代器
begin
end
以及一个键值“k”,并返回一个迭代器,该迭代器指向范围
[begin,end]
中第一个出现的k,或者如果未找到
k
,则返回一个迭代器。当然,您可以自己实现find函数,如下所示:

string::size_type pos=string::npos;
for(string::size_type i=0; i<s.size(); ++i) {
  if(s[i] == key) {
     pos=i;
     break;
  }
}
if(pos != string::npos) {
  // key was found
} else {
  // not found
}
有关
std::string::find
std::find
的详细信息:


鉴于您的陈述,您希望比string::find更快,我唯一能想到的是创建一个具有高度自定义赋值运算符的类,该类在每次更新字符串时都会更新一个内部表,其中包含字符串中每个可能字符的第一个位置(256表示字符字符串,65536(?)表示宽字符串)。这需要O(1)查找,而非常量操作会增加相当多的复杂性。

另一种方法是对相应的c_str字符串使用strhr函数:

if(strchr(str.c_str(), '|'))
{
    \\found
}
不知道它在速度方面与std find相比如何

找到的字符的位置为

size_t pos = strchr(str.c_str(),'|') - str.c_str();

添加Tom Tanner的答案。如果你不想做任何先验计算,你将被困在O(n)上,即搜索字符串的长度与时间消耗之间存在线性相关性。Tom建议设置一个数组(或向量)表示是否出现某个字符的布尔值。需要一次O(n)来索引字符串,但如果包含O(1)(常数时间),则可以检查O(1)中的任意数量的字符。这种方法的缺点是需要大量内存(一旦决定需要支持unicode)

作为一种折衷方法,您可以使用std::set或类似工具,只存储输入字符串中实际存在的字符。内存消耗与字符串中不同字符的数量大致呈线性关系,但查找时间为O(对数n),即对数

当然,您应该测量/分析,然后在此解释您实际优化的用例。在此之前,请坚持使用最容易理解和阅读的内容。

使用Visual Studio 2013编译器进行的实证测试表明,strchr例程大约比std::str快2倍ing::查找实现。

您可以尝试以下方法:

   string s1 = "Hello";
   string s2 = "el";
   if(strstr(s1.c_str(),s2.c_str()))
   {
    cout << " S1 Contains S2";
   }
string s1=“你好”;
字符串s2=“el”;
if(strstrstr(s1.c_str(),s2.c_str())
{

无法查看
std::string
参考,您最终会找到
find
。这取决于您使用的字符串的“形式”。请在标题中避免使用“最佳”和“最快”;前者[几乎]应该避免,因为它增加的价值很小(“最佳”答案中会给出“最佳”方式),后者应该避免,除非有一个特定的测试用例/场景,其中常见的方法“不够快”(这需要先有一些东西来比较!)@chris我知道string find,但是有没有比我的问题更有效的东西。不太可能有比这更有效的东西。O(n)是您所能做的最好的。标准库实现应该非常优化。“如果找不到字符,函数将返回空指针”。因此,在您的示例中,在这种情况下,您是从空指针进行减法。指针溢出是UB。@namezero这就是为什么我们在尝试通过减法获取pos之前先使用if语句,因此如果找不到字符,我们不会尝试获取pos。@Peter yeah显然我们需要提供我们正在寻找的字符。。(已修复)
size_t pos = strchr(str.c_str(),'|') - str.c_str();
   string s1 = "Hello";
   string s2 = "el";
   if(strstr(s1.c_str(),s2.c_str()))
   {
    cout << " S1 Contains S2";
   }