我有两个字符串需要进行比较:String
和 String:
。是否有库函数能够接收这两个字符串并返回true,但当传入String
和OtherString
时返回false?
准确地说,我想知道一个字符串是否是另一个字符串的前缀。
我有两个字符串需要进行比较:String
和 String:
。是否有库函数能够接收这两个字符串并返回true,但当传入String
和OtherString
时返回false?
准确地说,我想知道一个字符串是否是另一个字符串的前缀。
使用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.
}
begin()
比较而不是 end
来扩展到测试共享前缀而不是前缀本身(并且可以通过减去来获取共同前缀的实际长度)。 - David Rodríguez - dribeasfoo.size() <= foobar.size()
。 - Benoita.size() >= b.size()
?compare()
也可以处理这个问题。 - onya.compare
在到达 a
的末尾时会停止,不会查看 b
的剩余字符。如果 b
在末尾包含额外的字符,则它不是 a
的前缀。 - Neil Mayhewstr
的结尾处相等。对于AA
和B
,它们在第一个字符上不同,因此compare
将返回非零结果。答案本身的措辞更清晰。 - Neil Mayhew如果你知道哪个字符串更短,那么这个过程很简单,只需要先使用较短的字符串来调用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() );
}
std::string(X).find(Y)
的结果为零,当且仅当 Y
是 X
的前缀。
Y
。 - MSaltersX
很长而且Y
不是X
的前缀)。 - Frerich Raabestd::string_view
:) - Rakete1111在 C++20 版本之后,我们可以使用 starts_with 函数来检查一个字符串是否以给定的前缀开头。
str.starts_with(prefix)
此外,还可以使用ends_with函数来检查后缀。
使用string::compare,您应该能够编写如下代码:
bool match = (0 == s1.compare(0, std::min(s1.length(), s2.length()), s2, 0, std::min(s1.length(), s2.length())));
或者,如果我们不想使用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;
}
string1
非常长,这种方法可能效率低下 - 调用 length()
是 O(n) 的,而且没有必要知道字符串的确切长度。你只需要知道它是否足够长即可。 - Frerich Raabecharacter_traits
表格?请注意,我的翻译可能不够完美,但我会尽力确保翻译的准确性和易读性。 - MSalters\0
。 - Vladlength()
函数必须在常数时间内完成;而在C++03中,它应该在常数时间内完成。 - Mike Seymourbegin()
和 end()
,迭代器是随机的,因此它们可以在常数时间内进行减法运算,差值就是字符串的大小,因此必须在常数时间内 知道 它。2) 除非字符串使用 ropes(在 C++11 中被禁止,在任何 已知 的现行标准库实现中都未被实现),否则内存是连续的,这意味着 知道 begin()
和 end()
和 知道 size()
是等价的,你需要存储其中两个,并且可以在常数时间内计算出另一个。 - David Rodríguez - dribeas如果你可以合理地忽略任何多字节编码(比如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;
}
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() );
}
只需要这样:
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++不是C语言,它更加安全、简单和高效。
已经测试过的环境包括:
#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;
}
std::string_view
代替:#include <string>
#include <string_view>
bool prefix(const std::string& a, const std::string& b) {
if (a.size() > b.size()) {
return std::string_view(a.c_str(),b.size()) == b;
}
else {
return std::string_view(b.c_str(),a.size()) == a;
}
}
使用g++ 7的-O3优化选项后,这将折叠为单个memcmp
调用,相比旧版本而言,这是一个相当大的改进。
std::for_each
+ lambda 表达式,而不是噪音较少的范围 for 循环? - R. Martinho Fernandes最简单的方法是使用substr()和compare()成员函数:
string str = "Foobar";
string prefix = "Foo";
if(str.substr(0, prefix.size()).compare(prefix) == 0) cout<<"Found!";
substr()
,你可以简单地写成 str.substr(0, prefix.size()) == prefix
。 - ony对于 C++14 或更早版本的编程:
bool has_prefix
(const std::string& str, const std::string& prefix) {
return str.find(prefix, 0) == 0;
}
对于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;
}
str
比prefix
长,那么这种方法不会比其他方法慢很多吗?因为find()
方法会在str
中搜索任何prefix
的实例,即使它不在偏移量0处。例如,在前缀为“a”的情况下检查“bbbbbbba”需要搜索整个字符串,找到最后一个“a”,然后返回false,因为它不在偏移量零,而不是仅比较第一个字符后返回false。 - TrentP
string.compare()
怎么样? - Alok Saven
了。 - fredley==
运算符。;-) - Frerich Raabe