检查一个字符串是否是另一个字符串的前缀
我有两个要比较的字符串:String
和 String:
。是否有一个库函数在传递这两个字符串时返回 true,但对于 String
和 OtherString
则返回 false?
准确地说,我想知道一个字符串是否是另一个字符串的前缀。
I have two strings which I'd like to compare: String
and String:
. Is there a library function that would return true when passed these two strings, but false for say String
and OtherString
?
To be precise, I want to know whether one string is a prefix of another.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
使用
std::mismatch
。传入较短的字符串作为第一个迭代器范围,较长的字符串作为第二个迭代器范围。返回的是一对迭代器,第一个是第一个范围中的迭代器,第二个是第二个范围中的迭代器。如果第一个是第一个范围的末尾,那么您知道短字符串是较长字符串的前缀,例如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.这既高效又方便:
compare
速度很快,因为它使用快速的traits::compare
方法,并且不需要复制任何数据。在这里,它将比较 std::min(str.size(), pre.size()) 字符,但如果两个范围中的字符相等,它还会检查 pre 的长度 并在
pre
长于此值时返回非零值。请参阅 cplusplus.com 上的文档。
我编写了一个 测试程序,它使用此代码来比较命令行上给出的前缀和字符串。
This is both efficient and convenient:
compare
is fast because it uses the fasttraits::compare
method and doesn't have to copy any data.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 ofpre
and returns a non-zero value ifpre
is longer than this.See the documentation at cplusplus.com.
I've written a test program that uses this code to compare prefixes and strings given on the command line.
如果您知道哪个字符串更短,则过程很简单,只需使用
std::equal
首先是较短的字符串。如果你不这样做,有什么像下面这样应该有效:
If you know which string is shorter, the procedure is simple, just use
std::equal
with the shorter string first. If you don't, somethinglike the following should work:
当且仅当
Y
是X
的前缀时,std::string(X).find(Y)
为零std::string(X).find(Y)
is zero if and only ifY
is a prefix ofX
在 C++20 之后,我们可以使用 starts_with 来检查字符串是否以给定的前缀开头。
另外,还有 ends_with 来检查后缀
After C++20, we can use starts_with to check if a string begins with given prefix.
Also, there is ends_with to check suffix
使用 string::compare,您应该能够编写如下内容:
<代码> bool match = (0==s1.compare(0, min(s1.length(), s2.length()), s2,0,min(s1.length(),s2.length()))) ;
或者,如果我们不想使用
length()
成员函数:With string::compare, you should be able to write something like:
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:如果您可以合理地忽略任何多字节编码(例如UTF-8),那么您可以使用
strncmp
为此:如果您坚持使用奇特的 C++ 版本,则可以使用
std::equal
算法(还有一个好处是你的函数也适用于其他集合,而不仅仅是字符串):If you can reasonably ignore any multi-byte encodings (say, UTF-8) then you can use
strncmp
for this:If you insist on using a fancy C++ version, you can use the
std::equal
algorithm (with the added benefit that your function also works for other collections, not just strings):简单来说怎么样:
C++而不是C,安全、简单、高效。
测试:
如果您有 C++17,您可以使用
std::string_view
编写更好的版本:使用 g++ 7 at -O3,这会折叠为单个
memcmp
code> 调用,这比旧版本有相当大的改进。How about simply:
C++ not C, safe, simple, efficient.
Tested with:
If you have C++17 you can write a better version of this, using
std::string_view
instead:With g++ 7 at -O3 this collapses to a single
memcmp
call, which is a fairly substantial improvement over the older version.最简单的方法是使用 substr() 和 compare() 成员函数:
Easiest way is to use substr() and compare() member functions:
如果在 str1 的索引 0 处找到整个 str2,则 str1.find(str2) 返回 0:
输出:
str1.find(str2) returns 0 if entire str2 is found at the index 0 of str1:
Output:
“查找”并检查位置 0 的结果有什么问题?
What's wrong with the "find" and checking the result for position 0 ?
我认为
strncmp
最接近您正在寻找的内容。不过,如果改写的话,您可能会寻找
strstr(s2,s1)==s2
,这不一定是最有效的方法。但你不想算出n
;-)好吧,好吧,C++ 版本将是
!s1.find(s2)
。好吧,你可以让它更加c++,像这样: std::mismatch(s1.begin(),s1.end(),s2.begin()).first==s1.end()< /代码>。
I think
strncmp
is the closest to what you're looking for.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 outn
;-)Okay, okay, the c++ version would be
!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 ++ 14或更少
对于c ++ 17
You can use this:
for c++14 or less
for c++17