C++ 字符串匹配实现
我编写了下面的代码来检查文本中是否存在certin字符串。问题是C++ 字符串匹配实现,c++,string,pattern-matching,string-matching,C++,String,Pattern Matching,String Matching,我编写了下面的代码来检查文本中是否存在certin字符串。问题是match()函数总是返回false即使文本中存在模式 int main(){ char *text="hello my name is plapla"; char *patt="my"; cout<<match(patt,text); system("pause"); return 0; } bool match(char* patt,char* text){
match()
函数总是返回false
即使文本中存在模式
int main(){
char *text="hello my name is plapla";
char *patt="my";
cout<<match(patt,text);
system("pause");
return 0;
}
bool match(char* patt,char* text){
int textLoc=0, pattLoc=0, textStart=0;
while(textLoc <= (int) strlen(text) && pattLoc <= (int)strlen(patt)){
if( *(patt+pattLoc) == *(text+textLoc) ){
textLoc= textLoc+1;
pattLoc= pattLoc+1;
}
else{
textStart=textStart+1;
textLoc=textStart;
pattLoc=0;
}
}
if(pattLoc > (int) strlen(patt))
return true;
else return false;
}
intmain(){
char*text=“你好,我的名字是plapla”;
char*patt=“我的”;
cout在while
循环中尝试pattLoc<(int)strlen(patt)
。
循环将在pattLoc==2
时停止,因此您避免将“my”
的'\0'
与“hello my name is pala”
的'
进行比较,后者将pattLoc
设置为0
并返回false
或者更好,在while
循环中使用stringsubstr尝试pattLoc<(int)strlen(patt)
。
循环将在pattLoc==2
时停止,因此您避免将“my”
的'\0'
与“hello my name is pala”
的'
进行比较,后者将pattLoc
设置为0
并返回false
或者更好地使用string
substr
显而易见的解决方案是:
bool
match( std::string const& pattern, std::string const& text )
{
return std::search( text.begin(), text.end(),
pattern.begin(), pattern.end() )
!= text.end();
}
<>这是习惯C++,我希望任何C++程序员都能这样做。
至少在专业环境中写
如果目标是学习如何编写这样的函数,那么当然,
以上不是一个很好的解决方案。那么解决方案应该是mroe
分而治之;match
中的内容太多了,你无法把它放进去
在一个函数中,我推荐如下内容:
bool
startsWith( std::string::const_iterator begin,
std::string::const_iterator end,
std::string const& pattern )
{
return end - begin >= pattern.size()
&& std::equal( pattern.begin(), pattern.end(), begin );
}
bool
match( std::string const& pattern, std::string const& text )
{
std::string::const_iterator current = text.begin();
while ( current != text.end()
&& !startsWith( begin, text.end(), pattern ) ) {
++ current;
}
return current != text.end();
}
这显然是可以改进的;例如,这是没有意义的
当剩余文本的长度为
小于图案的长度
如果你的教授坚持要你使用char const*(如果他坚持的话
在char*
,那么他完全不称职,应该被解雇),这
可以很容易地重写:只需将对begin
的所有调用替换为
指针,以及对
的所有调用都使用指针+strlen(指针)
结束。显而易见的解决方案是:
bool
match( std::string const& pattern, std::string const& text )
{
return std::search( text.begin(), text.end(),
pattern.begin(), pattern.end() )
!= text.end();
}
<>这是习惯C++,我希望任何C++程序员都能这样做。
至少在专业环境中写
如果目标是学习如何编写这样的函数,那么当然,
以上不是一个很好的解决方案。那么解决方案应该是mroe
分而治之;match
中的内容太多了,你无法把它放进去
在一个函数中,我推荐如下内容:
bool
startsWith( std::string::const_iterator begin,
std::string::const_iterator end,
std::string const& pattern )
{
return end - begin >= pattern.size()
&& std::equal( pattern.begin(), pattern.end(), begin );
}
bool
match( std::string const& pattern, std::string const& text )
{
std::string::const_iterator current = text.begin();
while ( current != text.end()
&& !startsWith( begin, text.end(), pattern ) ) {
++ current;
}
return current != text.end();
}
这显然是可以改进的;例如,这是没有意义的
当剩余文本的长度为
小于图案的长度
如果你的教授坚持要你使用char const*
(如果他坚持的话
在char*
,那么他完全不称职,应该被解雇),这
可以很容易地重写:只需将对begin
的所有调用替换为
指针,以及使用指针+strlen(指针)
结束的所有调用我已解决了问题:
while(textLoc=(int)strlen(patt))
我已经解决了这个问题:
while(textLoc=(int)strlen(patt))
你为什么不使用std::string
?有什么特别的原因或者只是喜欢c?而不是*(patt+pattLoc)
你可以使用patt[pattLoc]
,但既然你喜欢C的某些部分,我认为textLoc
应该是一个char*
。也许这是家庭作业或编码练习。@Adban等等,那么你真的喜欢指针和原始内存管理?你真的想把strlen
移出循环,或者希望你的编译器很聪明。为什么不呢使用std::string
?有什么特别的原因或者只是喜欢c?而不是*(patt+pattLoc)
你可以使用patt[pattLoc]
,但既然你喜欢C的某些部分,我认为textLoc
应该是一个char*
。也许这是家庭作业或编码练习。@Adban等等,那么你真的喜欢指针和原始内存管理吗?你真的想把strlen
移出循环,或者希望你的编译器很聪明。string::suBSTR 可能比他多次调用<代码>斯特林< /C>(甚至远不能确定)性能更差。对于更好或更坏,C++库是围绕迭代器设计的。<代码>::Stras::/代码>可能比他多次调用<代码>斯特林< /C>更糟糕(尽管它还远远没有把握)。为了更好或更坏,C++库是围绕迭代器设计的。