字符串匹配

  对于字符串A,其中绝对不含有字符’.’和’’。再给定字符串B,其中可以含有’.’或’’,’’字符不能是B的首字符,并且任意两个’’字符不相邻。exp中的’.’代表任何一个字符,B中的’’表示’’的前一个字符可以有0个或者多个。请写一个函数,判断A是否能被B匹配。

#include <iostream>
#include <algorithm>
using namespace std;

/*
str:i  exp:j  bool f(i,j):str中i开头的字符串能否匹配exp中j开头的字符串
 j+1位置上是否为*
    1.j是最后一个字符
    2.j+1有字符不是*
        i位置的字符必须与j位置的字符相匹配成功(j位置字符与i位置相等或j位置为'.'),配不上直接返回false,如果配上再看j+1和i+1
    3.j+1位置有字符是*
        1>j位置字符为普通字符,考虑j+2配i开头的整体
        2>j位置与i位置字符匹配,考虑j+2位置与i开头以及以后相应的位置匹配(str的前缀不停变化)
*/
//暴力递归
bool match(const string &str,const string &exp,int i,int j)
{
    if(j==exp.size())
        return i==str.size();
    //j位置有字符
    if(j+1==exp.size()||exp.at(j+1)!='*')
        return i!=str.size()&&(str.at(i)==exp.at(j)||exp.at(j)=='.')&&match(str,exp,i+1,j+1);

    //j+1有字符且是'*'
    while(i!=str.size()&&(exp.at(j)==str.at(i)||exp.at(j)=='.'))
    {
        if(match(str,exp,i,j+2))
            return true;
        ++i;
    }
    return match(str,exp,i,j+2);
}

//dp
bool is_valid(const string &str,const string &exp)
{
    if(find(str.begin(),str.end(),'.')!=str.end()||find(str.begin(),str.end(),'*')!=str.end())
        return false;
    if(find(exp.begin(),exp.end(),'*')==exp.begin()||str.find("**")!=string::npos)
        return false;
    return true;
}

bool match1(const string& str, const string& exp)
{
    if(str.empty()||exp.empty())
        return false;
    if(!is_valid(str,exp))
        return false;

    //填表
    vector<vector<bool> > m(str.size()+1,vector<bool>(exp.size()+1));
    m.at(m.size()-1).at(m.at(0).size()-1)=true;
    for(int j=m.at(0).size()-2;j>=0;j-=2)
    {
        if(exp.at(j)!='*'&&exp.at(j+1)=='*')
            m.at(str.size()).at(j)=true;
        else
            break;
    }
    if(str.size()>0&&exp.size()>0)
        if(exp.at(exp.size()-1)=='.'||str.at(str.size()-1)==exp.at(exp.size()-1))
            m.at(str.size()-1).at(exp.size()-1)==true;

    for(int i=str.size()-1;i>=0;--i)
    {
        for(int j=exp.size()-2;j>=0;--j)
        {
            if(exp.at(j+1)!='*')
                m.at(i).at(j)=(str.at((i)==exp.at(j)||exp.at(j)=='.'))&&m.at(i+1).at(j+1);
            else
            {
                int si=i;
                while(si!=str.size()&&(str.at(si)==exp.at(j)||exp.at(j)=='.'))
                {
                    if(m.at(si).at(j+2))
                    {
                        m.at(i).at(j)=true;
                        break;
                    }
                    ++si;
                }
                if(m.at(i).at(j)!=true)
                    m.at(i).at(j)=m.at(si).at(j+2);
            }
        }
    }
    return m.at(0).at(0);
}
int main()
{
    string str("abc");
    string exp("a.c");
    cout<<match(str,exp,0,0)<<endl;
    cout<<match1(str,exp)<<endl;
    return 0;
}

 

posted on 2019-03-25 22:49  tianzeng  阅读(312)  评论(0编辑  收藏  举报

导航