检查一个字符串是否是另一个字符串的前缀
Check if one string is a prefix of another
我有两个字符串我想比较: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.
}
这样既高效又方便:
str.compare(0, pre.size(), pre) == 0
compare
是快速的,因为它使用快速的traits::compare
方法,不需要复制任何数据。
在这里,它将比较std::min(str.size(), pre.size())
字符,但如果两个范围中的字符相等,它也会检查pre
的长度,如果pre
大于此长度,则返回一个非零值。
请参阅cplusplus.com的文档。
我已经编写了一个测试程序,它使用这段代码来比较命令行上给出的前缀和字符串。
如果您知道哪个字符串更短,则过程很简单,只需使用首先使用较短字符串的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
的前缀
c++ 20之后,可以使用starts_with检查字符串是否以给定前缀开头。
str.starts_with(prefix)
还有ends_with来检查后缀
使用string::compare,您应该能够编写如下内容:
bool match = (0==s1.compare(0, min(s1.length(), s2.length()), s2,0,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;
}
如果您可以合理地忽略任何多字节编码(例如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;
}
如果你坚持使用一个花哨的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() );
}
这样简单:
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;
}
如果你有c++ 17,你可以写一个更好的版本,使用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
调用,这比旧版本有了相当大的改进。
最简单的方法是使用substr()和compare()成员函数:
string str = "Foobar";
string prefix = "Foo";
if(str.substr(0, prefix.size()).compare(prefix) == 0) cout<<"Found!";
str1.find(str2)如果在str1的索引0处找到整个str2,则返回0:
#include <string>
#include <iostream>
// does str1 have str2 as prefix?
bool StartsWith(const std::string& str1, const std::string& str2)
{
return (str1.find(str2)) ? false : true;
}
// is one of the strings prefix of the another?
bool IsOnePrefixOfAnother(const std::string& str1, const std::string& str2)
{
return (str1.find(str2) && str2.find(str1)) ? false : true;
}
int main()
{
std::string str1("String");
std::string str2("String:");
std::string str3("OtherString");
if(StartsWith(str2, str1))
{
std::cout << "str2 starts with str1" << std::endl;
}
else
{
std::cout << "str2 does not start with str1" << std::endl;
}
if(StartsWith(str3, str1))
{
std::cout << "str3 starts with str1" << std::endl;
}
else
{
std::cout << "str3 does not start with str1" << std::endl;
}
if(IsOnePrefixOfAnother(str2, str1))
{
std::cout << "one is prefix of another" << std::endl;
}
else
{
std::cout << "one is not prefix of another" << std::endl;
}
if(IsOnePrefixOfAnother(str3, str1))
{
std::cout << "one is prefix of another" << std::endl;
}
else
{
std::cout << "one is not prefix of another" << std::endl;
}
return 0;
}
输出: str2 starts with str1
str3 does not start with str1
one is prefix of another
one is not prefix of another
查找和检查位置0的结果有什么问题?
string a = "String";
string b = "String:";
if(b.find(a) == 0)
{
// Prefix
}
else
{
// No Prefix
}
我认为strncmp
是最接近你所寻找的。
虽然,如果重新措辞,您可能会寻找strstr(s2,s1)==s2
,这不一定是最有效的方法。但是你不想算出n
;-)
好的,好的,c++版本应该是!s1.find(s2)
。
好的,你可以把它写得更像c++,像这样:std::mismatch(s1.begin(),s1.end(),s2.begin()).first==s1.end()
.
你可以这样做:
for 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;
}
bool IsPrefix(const std::string& prefix, const std::string& whole)
{
return whole.size() >= prefix.size() && whole.compare(0, prefix.size(), prefix) == 0;
}
- 使用 SET(C++) 检查两个给定字符串是否是字谜时出现运行时错误
- 检查字符串是否是拉平德罗姆
- 检查字符串是否是数字,然后将该数字转换为 int?
- 是否可以动态检查文本字符串是否是 C++ 中给定类的成员?
- 检查字母字符串是否是C 中的palindrome
- 如何测试字符串是否是有效的C++(ish)表达式
- 是正则是查看字符串是否是另一个弦的好方法
- 检查一个字符串是否是另一个字符串的排列C++
- 如何检查字符串是否是另一个字符串的正确子集
- 有条件地确定字符串是否是数组的一部分
- 查找 N 个字符串是否是彼此的字谜
- 有没有一种快速的方法来检查字符串是否是数字
- 如何搜索字符串是否是存储在集合中的字符串的前缀
- 如何检查字符串是否是一定数量的字符并且包含(或不包含)某些字符?C++
- 检查一个字符串是否是另一个字符串的前缀
- 检查一个字符串是否是另一个字符串的排列
- 检查字符串是否是映射的一部分
- 如何检查指定的字符串是否是有效的URL或是否使用C++代码
- visualstudio2008-如何确定字符串是否是C++中的有效IPv6地址
- 如何找出一个字符串是否是随机的在C/ c++