【问题标题】:String matching implementation字符串匹配实现
【发布时间】:2012-02-23 11:39:39
【问题描述】:

我编写了以下代码来检查文本中是否存在 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){

    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;
}

【问题讨论】:

  • 你为什么不使用std::string?有什么特别的原因还是只是喜欢c?
  • 你可以使用patt[pattLoc]而不是*(patt+pattLoc),但由于你喜欢C的部分内容,我认为textLoc应该是char *
  • 也许这是家庭作业或编码练习。
  • @Adban 等等,所以你实际上喜欢指针和原始内存管理
  • 真的想要将strlens移到循环之外,或者希望你的编译器很聪明。

标签: c++ string pattern-matching string-matching


【解决方案1】:

在您的while 循环中尝试pattLoc &lt; (int)strlen(patt)。 当pattLoc == 2 时循环将停止,因此您避免将"my"'\0'"hello my name is pala"' ' 进行比较,后者将pattloc 设置为0return false

或者更好,使用字符串substr

【讨论】:

  • string::substr 的性能可能比他多次调用strlen 的性能更差(尽管还不确定)。无论好坏,C++ 库都是围绕迭代器设计的。
【解决方案2】:

显而易见的解决方案是:

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 的调用替换为 指针,以及对end 的所有调用pointer + strlen(pointer)

【讨论】:

    【解决方案3】:

    我已经解决了这个问题:

    while(textLoc &lt;= (int) strlen(text) &amp;&amp; pattLoc &lt;= (int)strlen(patt))

    应该是:

    while(textLoc &lt; (int) strlen(text) &amp;&amp; pattLoc &lt; (int)strlen(patt))

    if(pattLoc &gt; (int) strlen(patt))if(pattLoc &gt;= (int) strlen(patt))

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-12
      • 1970-01-01
      • 2020-10-31
      相关资源
      最近更新 更多