Реализация соответствия строк - PullRequest
1 голос
/ 31 января 2012

Я написал приведенный ниже код, чтобы проверить, существует ли определенная строка в тексте или нет.Проблема в том, что функция 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;
}

Ответы [ 3 ]

3 голосов
/ 31 января 2012

Попробуйте pattLoc < (int)strlen(patt) в вашем while цикле. Цикл остановится, когда pattLoc == 2, поэтому вы не будете сравнивать '\0' из "my" с ' ' из "hello my name is pala", в котором для pattloc установлено 0 и return false.

Или лучше, используйте строку substr.

1 голос
/ 31 января 2012

Очевидное решение:

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 ++ напишите это, по крайней мере, в профессиональной среде.

Если цель состоит в том, чтобы научиться писать такую ​​функцию, то, конечно, вышеупомянутое не большая часть решения. Решение тогда должно быть мрое разделяй и властвуй; слишком много в 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();
}

Это, очевидно, можно улучшить; например, нет смысла в продолжается в цикле while, когда длина оставшегося текста меньше длины шаблона.

И если ваш профессор настаивает на том, чтобы вы использовали char const* (если он настаивает на char*, тогда он совершенно некомпетентен и должен быть уволен), это можно легко переписать для этого: просто замените все вызовы на begin на указатель и все звонки на end с pointer + strlen(pointer).

0 голосов
/ 31 января 2012

Я решил проблему:

while(textLoc <= (int) strlen(text) && pattLoc <= (int)strlen(patt))

должно быть:

while(textLoc < (int) strlen(text) && pattLoc < (int)strlen(patt))

и if(pattLoc > (int) strlen(patt)) до if(pattLoc >= (int) strlen(patt))

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...