匹配字符串中的序列

时间:2014-01-28 19:10:34

标签: c++ string algorithm data-structures

给出三个字符串序列“abb”“ab”“a”。

现在我需要找到算法来检查字符串是否可以通过上面的序列解析。例如

  

字符串“abbabab”可以通过序列“abb”“ab”和“ab”解析

     

字符串“abbbaaa”它无法解析,因为我们没有“b”序列。

我已经编写了以下代码,但我觉得它不是正确的算法。任何建议。

bool checkIsStringCanBeParsed(std::string S) {

    std::string seqArray[6]={"abb","ab","a","abb","ab","a"};

    int index=0;
    int lastIndex=0;
    for(int i=0;i<6;++i)
    {
        lastIndex =index;
        for(int idx=0;idx<seqArray[i].length();++idx)
        {

            if(index >= S.length())
            {
                index =lastIndex;
                break;
            }
            if(S[index] == seqArray[i][idx])
            {

                ++index;
                continue;
            }
            else
                break;


        }
        if(index == S.length())
            return true;

    }
    return false;
}

3 个答案:

答案 0 :(得分:1)

您要做的是构建一个接受表达式(abb | ab | a)*中的句子的正则表达式引擎,一个选项是使用non deterministic automata来表示该正则表达式。使用此tool我能够生成:

nda for (abb|ab|b)

这里我们有一个包含3个状态的图表。当您想要查看规则是否接受给定字符串时,它必须被此图表接受,通过接受它意味着通过char读取字符串char,您应该能够使用有效步骤在图表中导航。解析字符串时,应始终从状态0开始。

例如字符串“aaba”将引导我们进入状态0,状态1,状态1,状态2,状态1,因此字符串是有效的,因为我们能够完全解析它。字符串“abbb”将引导我们进入状态0,状态1,状态2,状态3但是没有办法从状态3使用另一个'b',因此该字符串无效。

伪代码执行此操作:

boolean accept(word, state)
{
    if(word.length == 0) //either the string is empty or the parsing has ended succesfully
    {
        return true;
    }
    else
    {
        parsingChar = word[0] //first char of string

        switch state
            case 0:
                if (parsingChar == 'a')
                    return accept(substring(word,1),1); //recursive call, we remove the first char and move to state 1
                else
                    return false; // the first char is not an 'a' the word is not accepted
                break;
            case 1:
                if (parsingChar == 'a')
                    return accept(substring(word,1),3); // move to state 3
                else if (parsingChar == 'b')
                    return accept(substring(word,1),2); // move to state 2
                else
                    return false; //
                break;
            case 2:
                if (parsingChar == 'a')
                    return accept(substring(word,1),3); // move to state 3
                else if (parsingChar == 'b')
                    return accept(substring(word,1),1); // move to state 1
                else
                    return false; //
                break;
            case 3:
                if (parsingChar == 'a')
                    return accept(substring(word,1),1); // move to state 1
                else
                    return false;
                break;
    }

}

答案 1 :(得分:0)

你应该使用正则表达式。序列的正则表达式是“^((abb)|(ab)|(a))* $”。正则表达式库将为您优化它。

答案 2 :(得分:0)

动态编程应该可以正常工作。假设dp(i)= true,当且仅当有可能用给定序列解析长度为i的前缀时。最初,dp(0)=真。然后可以通过以下方式计算所有i的dp值:如果dp(j)= true并且从j + 1到i的子串匹配其中一个序列,则dp(i)= true。