• 字符串匹配


      对于字符串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;
    }
  • 相关阅读:
    汉语-词语-从容:百科
    汉语-词语-伶俜:百科
    汉语-词语-心迹:百科
    汉语-词语-痛楚:百科
    汉语-词语-痛苦:百科
    汉语-词语:散步
    汉语-词语-憎恨:百科
    2455 繁忙的都市
    P2820 局域网
    NOIP2013Day1T3 表示只能过一个点
  • 原文地址:https://www.cnblogs.com/tianzeng/p/10597364.html
Copyright © 2020-2023  润新知