C++ 检查一个字符串是否是另一个字符串的前缀

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7913835/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:42:22  来源:igfitidea点击:

Check if one string is a prefix of another

c++string-comparisonprefix

提问by fredley

I have two strings which I'd like to compare: Stringand String:. Is there a library function that would return true when passed these two strings, but false for say Stringand OtherString?

我有两个要比较的字符串:StringString:。是否有一个库函数在传递这两个字符串时会返回 true,而 sayString和 则返回 false OtherString

To be precise, I want to know whether one string is a prefix of another.

准确地说,我想知道一个字符串是否是另一个字符串的前缀。

回答by Nim

Use std::mismatch. Pass in the shorter string as the first iterator range and the longer as the second iterator range. The return is a pair of iterators, the first is the iterator in the first range and the second, in the second rage. If the first is end of the first range, then you know the the short string is the prefix of the longer string e.g.

使用std::mismatch. 将较短的字符串作为第一个迭代器范围传入,将较长的字符串作为第二个迭代器范围传入。返回是一对迭代器,第一个是第一个范围中的迭代器,第二个是第二个范围中的迭代器。如果第一个是第一个范围的结尾,那么您知道短字符串是较长字符串的前缀,例如

std::string foo("foo");
std::string foobar("foobar");

auto res = std::mismatch(foo.begin(), foo.end(), foobar.begin());

if (res.first == foo.end())
{
  // foo is a prefix of foobar.
}

回答by James Kanze

If you know which string is shorter, the procedure is simple, just use std::equalwith the shorter string first. If you don't, something like the following should work:

如果您知道哪个字符串较短,则过程很简单,只需先使用 std::equal较短的字符串即可。如果您不这样做,则应该可以使用以下内容:

bool
unorderIsPrefix( std::string const& lhs, std::string const& rhs )
{
    return std::equal(
        lhs.begin(),
        lhs.begin() + std::min( lhs.size(), rhs.size() ),
        rhs.begin() );
}

回答by MSalters

std::string(X).find(Y)is zero if and only if Yis a prefix of X

std::string(X).find(Y)为零当且仅当Y是 的前缀X

回答by Neil Mayhew

This is both efficient and convenient:

这既高效又方便:

str.compare(0, pre.size(), pre) == 0

compareis fast because it uses the fast traits::comparemethod and doesn't have to copy any data.

compare速度快是因为它使用了快速traits::compare方法并且不需要复制任何数据。

Here, it will compare std::min(str.size(), pre.size())characters but if the characters in the two ranges are equal it also checks the length of preand returns a non-zero value if preis longer than this.

在这里,它会比较std::min(str.size(), pre.size())字符,但如果两个范围内的字符相等,它还会检查 的长度pre并返回一个非零值,如果pre长度超过这个值。

See the documentationat cplusplus.com.

请参阅cplusplus.com 上的文档

回答by Vlad

With string::compare, you should be able to write something like:

使用string::compare,您应该能够编写如下内容:

bool match = (0==s1.compare(0, min(s1.length(), s2.length()), s2,0,min(s1.length(),s2.length())));

bool match = (0==s1.compare(0, min(s1.length(), s2.length()), s2,0,min(s1.length(),s2.length())));

Alternatively, in case we don't want to use the length()member function:

或者,如果我们不想使用length()成员函数:

bool isPrefix(string const& s1, string const&s2)
{
    const char*p = s1.c_str();
    const char*q = s2.c_str();
    while (*p&&*q)
        if (*p++!=*q++)
            return false;
    return true;
}

回答by Frerich Raabe

Ifyou can reasonably ignore any multi-byte encodings (say, UTF-8) then you can use strncmpfor this:

如果您可以合理地忽略任何多字节编码(例如 UTF-8),那么您可以使用strncmp

// Yields true if the string 's' starts with the string 't'.
bool startsWith( const std::string &s, const std::string &t )
{
    return strncmp( s.c_str(), t.c_str(), t.size() ) == 0;
}

If you insist on using a fancy C++ version, you can use the std::equalalgorithm (with the added benefit that your function also works for other collections, not just strings):

如果您坚持使用花哨的 C++ 版本,则可以使用该std::equal算法(附加的好处是您的函数也适用于其他集合,而不仅仅是字符串):

// Yields true if the string 's' starts with the string 't'.
template <class T>
bool startsWith( const T &s, const T &t )
{
    return s.size() >= t.size() &&
           std::equal( t.begin(), t.end(), s.begin() );
}

回答by Flexo

How about simply:

简单地说:

bool prefix(const std::string& a, const std::string& b) {
  if (a.size() > b.size()) {
    return a.substr(0,b.size()) == b;
  }
  else {
    return b.substr(0,a.size()) == a;
  }
}

C++ not C, safe, simple, efficient.

C++ 不是 C,安全、简单、高效。

Tested with:

测试:

#include <string>
#include <iostream>

bool prefix(const std::string& a, const std::string& b);

int main() {
  const std::string t1 = "test";
  const std::string t2 = "testing";
  const std::string t3 = "hello";
  const std::string t4 = "hello world";
  std::cout << prefix(t1,t2) << "," << prefix(t2,t1) << std::endl;
  std::cout << prefix(t3,t4) << "," << prefix(t4,t3) << std::endl;
  std::cout << prefix(t1,t4) << "," << prefix(t4,t1) << std::endl;
  std::cout << prefix(t1,t3) << "," << prefix(t3,t1) << std::endl;

}

回答by Flexo

Easiest way is to use substr()and compare()member functions:

最简单的方法是使用substr()compare()成员函数:

string str = "Foobar";
string prefix = "Foo";

if(str.substr(0, prefix.size()).compare(prefix) == 0) cout<<"Found!";

回答by xninja

You can use this:

你可以使用这个:

for c++14 or less

对于 c++14 或更少

bool has_prefix
    (const std::string& str, const std::string& prefix)  {
    return str.find(prefix, 0) == 0;
}

for c++17

对于 C++17

//it's a little faster
auto has_prefix
    (const std::string& str, const std::string_view& prefix) -> decltype(str.find(prefix) == 0) {
    return str.find(prefix, 0) == 0;
}

回答by Michael Krelin - hacker

I think strncmpis the closest to what you're looking for.

我认为strncmp是最接近你正在寻找的。

Though, if reworded, you may be looking for strstr(s2,s1)==s2, which is not necessarily the most performant way to do that. But you do not want to work out n;-)

但是,如果重新措辞,您可能正在寻找strstr(s2,s1)==s2,这不一定是最高效的方法。但你不想锻炼n;-)

Okay, okay, the c++ version would be !s1.find(s2).

好的,好的,C++ 版本将是!s1.find(s2).

Okay, you can make it even more c++, something like this: std::mismatch(s1.begin(),s1.end(),s2.begin()).first==s1.end().

好了,你可以把它更是C ++,是这样的:std::mismatch(s1.begin(),s1.end(),s2.begin()).first==s1.end()