#牛客#代码实现:字符串的匹配、字符串的交错组成、纸牌博弈、表达式组合

第一题:字符串与含有通用字符.*的字符串匹配问题

#include 
#include
using namespace std;
/*Problem:字符串匹配问题
给定字符串str,其中绝对不含有字符’.’和’*’。再给定字符串exp,其中可以含有’.’或’*’,’*’字符不能是exp的首字符,
并且任意两个’*’字符不相邻。exp中的’.’代表任何一个字符,exp中的’*’表示’*’的前一个字符可以有0个或者多个。
请写一个函数,判断str是否能被exp匹配。
【举例】
str=“abc”,exp=“abc”。返回true。
str=“abc”,exp=“a.c”。exp中单个’.’可以代表任意字符,所以返回true。
str=“abcd”,exp=“.*”。exp中’*’的前一个字符是’.’,所以可表示任意数量的’.’字符,所以当exp是“....”时与“abcd”匹配,所以返回true。
str=“”,exp=“..*”。exp中’*’的前一个字符是’.’,可表示任意数量的’.’字符,但是”.*”之前还有一个’.’字符,该字符不受‘*’的影响,
    所以str起码得有一个字符才能被exp匹配。所以返回false。
*/
bool isValid(string str,string exp){
    for(int i=0;iif(str[i]=='.'||str[i]=='*')
            return false;
    for(int i=0;i<exp.size();i++)
        if(exp[i]=='*'&&(i==0||exp[i-1]=='*'))
            return false;
    return true;
}
bool process(string str,string exp,int si,int ei){
    if(ei==exp.size())//e
        return si==str.size();
    if(ei+1==exp.size()||exp[ei+1]!='*')//如果exp到最后一位,或者下一位不是*号时,
        return si!=str.size()&&(str[si]==exp[ei]||exp[ei]=='.')&&process(str,exp,si+1,ei+1);
    while(si!=str.size()&&(str[si]==exp[ei]||exp[ei]=='.')){//当exp下一位是*号,且满足条件时进行如下运算。
        if(process(str,exp,si,ei+2))
            return true;
        si++;
    }
    return process(str,exp,si,ei+2);//当exp下一位为*号,且不满足while循环条件时。
}
bool match(string str,string exp){
    if(str.empty()&&exp.empty())return false;
    if(!isValid(str,exp))
        return false;
    return process(str,exp,0,0);
}

int main()
{
    string  str="abcd";string exp="a..*d";
    bool flag=match(str,exp);
    cout << "Hello world!" <return 0;
}

第二题:字符串的交错组成问题

#include 
#include
#include
using namespace std;
/*Problem:字符串的交错组成
给定三个字符串str1,str2,aim。如果aim包含且仅包含来自str1 和str2 的所有字符,而且aim中的所属字符串字符之间保持原来的顺序。
则称aim是str1 和str2 的交错组成。实现一个函数,判断aim是否是str1 和str2 的交错组成。
for example:
str1=“AB”,str2=“12”。那么“AB12”、“A1B2”、“A12B”、“1A2B”和“1AB2”等等都是str1和str2交错组成。
*/
bool isCstring(string str1,string str2,string aim){
    if(str1.empty()||str2.empty()||aim.empty())
        return false;
    int n1=str1.size(),n2=str2.size(),len=aim.size();
    if((n1+n2)!=len)return false;

    vector<vector<bool>> dp(n1+1,vector<bool>(n2+1,false));
    dp[0][0]=true;
    for(int i=1;i1;i++){
        if(str1[i-1]!=aim[i-1])break;
        dp[i][0]=true;
        }
    for(int j=1;j1;j++){
        if(str2[j-1]!=aim[j-1])break;
        dp[0][j]=true;
    }
    for(int i=1;i1;i++){
        for(int j=1;j1;j++){
            if((str1[i-1]==aim[i+j-1]&&dp[i-1][j])||(str2[j-1]==aim[i+j-1]&&dp[i][j-1]))
                dp[i][j]=true;
        }
    }
    return dp[n1][n2];
}
bool isCstring1(string str1,string str2,string aim){
    if(str1.empty()||str2.empty()||aim.empty())
        return false;
    if(str1.size()+str2.size()!=aim.size())
        return false;

    string short_str=str1.size()<=str2.size()?str1:str2;
    string long_str=str1.size()>str2.size()?str1:str2;

    int short_n=short_str.size();
    int long_n=long_str.size();
    vector<bool> dp(short_n+1,false);
    dp[0]=true;
    for(int i=1;i<=short_n;i++){
        if(short_str[i-1]!=aim[i-1])break;
        dp[i]=true;
    }

    for(int i=1;i<=long_n;i++){
        dp[0]=dp[0]&&long_str[i-1]==aim[i-1];
        for(int j=1;j<=short_n;j++){
            if((dp[j]&&long_str[i-1]==aim[i+j-1])||(dp[j-1]&&short_str[j-1]==aim[i+j-1]))
                dp[j]=true;
        }
    }
    return dp[short_n];
}

int main()
{
    string str1 = "1234";
    string str2 = "abcd";
    string aim = "a1b23c4d";
    bool flag=isCstring(str1,str2,aim);
    bool flag1=isCstring1(str1,str2,aim);
    cout << "Hello world!" << flag<<"  "<return 0;
}

第三题:排成一条线的纸牌博弈问题

#include 
#include
#include
using namespace std;
/*Problem:排成一条线的纸牌博弈问题
给定一个整型数组arr,代表数值不同的纸牌排成一条线。玩家A和玩家B依次拿走每张纸牌,规定玩家A先拿,玩家B后拿,
【举例】
arr=[1,2,100,4]。
开始时玩家A只能拿走1或4。如果玩家A拿走1,则排列变为[2,100,4],接下来玩家B可以拿走2或4,然后继续轮到玩家A。
如果开始时玩家A拿走4,则排列变为[1,2,100],接下来玩家B可以拿走1或100,然后继续轮到玩家A。玩家A作为绝顶聪明的人不会先拿4,因为拿了4之后玩家B将拿走100。所以玩家A会先拿1,让排列变为[2,100,4],
接下来玩家B不管怎么选,100都会被玩家A拿走。玩家A会获胜,分数为101。所以返回101。
arr=[1,100,2]。
开始时玩家A不管拿1还是2,玩家B作为绝顶聪明的人,都会把100拿走。玩家B会获胜,分数为100。所以返回100。
但是每个玩家每次只能拿走最左或最右的纸牌,玩家A和玩家B都绝顶聪明。请返回最后获胜者的分数。
*/
int s(vector<int>&arr ,int i,int j);
int f(vector<int>& arr,int i,int j){
if(i==j)return arr[i];
    return    max(arr[i]+s(arr,i+1,j),arr[j]+s(arr,i,j-1));
}
int s(vector<int>&arr,int i,int j){
if(i==j)return 0;
return min(f(arr,i+1,j),f(arr,i,j-1));
}
int sumOfarr(vector<int>&arr){
    if(arr.empty())return 0;
    int n=arr.size();
    return max(f(arr,0,n-1),s(arr,0,n-1));

}

int sumOfarr2(vector<int>&arr){
    if(arr.empty())return 0;
    int n=arr.size();
    vector<vector<int>>f(n,vector<int>(n));//(i,j)区域内,先选者的得分。
    vector<vector<int>>s(n,vector<int>(n));//(i,j)区域内,后选者的得分。
    for(int i=0;ifor(int j=i-1;j>=0;j--){
            f[j][i]=max(arr[j]+s[j+1][i],arr[i]+s[j][i-1]);
            s[j][i]=min(f[j+ 1][i],f[j][i-1]);
        }
    }
    return max(f[0][n-1],s[0][n-1]);
}
int main()
{
    vector<int> arr={1,100,2};
    int res1=sumOfarr(arr);
    int res=sumOfarr2(arr);
    cout << "Hello world!" <" "<return 0;
}

第四题:表达式得到期望结果的组成种数

#include 
#include
#include
using namespace std;
/*Problem:表达式得到期望结果的组成种数
给定一个只由0、1、&、|和^五种字符组成的字符串express,再给定一个布尔值desired。
返回express能有多少种组合方式,可以达到desired的结果。
for example:
express=“1^0|0|1”,desired=false。
只有1^((0|0)|1)和1^(0|(0|1))的组合可以得到false。返回2。
express=“1”,desired=false。
没有组合可以得到false。返回0。

*/\
bool isValid(string express){
    if(express.size()&1==0)//表达式长度为奇数
        return false;
    for(int i=0;i2){
        if(express[i]!='0'&&express[i]!='1')
            return false;
        if((i+11]=='0'||express[i+1]=='1'))
            return false;
    }
    return true;
}
int process(string str,bool desired,int left,int right){
    if(left==right){
        if(str[left]=='1')
            return desired ? 1:0;
        else
            return desired ? 0:1;

        }
    int res=0;
    if(desired){
        for(int i=left+1;i<=right;i+=2){
            switch(str[i]){
            case '&':
                res+=process(str,true,left,i-1)*process(str,true,i+1,right);
                break;
            case '|':
                res+=(process(str,true,left,i-1)+process(str,false,left,i-1))*process(str,true,i+1,right)+process(str,true,left,i-1)*process(str,false,i+1,right);
                break;
            case '^':
                res+=process(str,true,left,i-1)*process(str,false,i+1,right)+process(str,false,left,i-1)*process(str,true,i+1,right);
                break;
            }
        }
    }
    else{
        for(int i=left+1;i<=right;i+=2){
            switch(str[i]){
        case '&'://false
            res+=(process(str,true,left,i-1)+process(str,false,left,i-1))*process(str,false,i+1,right)+process(str,false,left,i-1)*process(str,true,i+1,right);
            break;
        case '|':
            res+=process(str,false,left,i-1)*process(str,false,i+1,right);
            break;
        case '^':
            res+=process(str,true,left,i-1)*process(str,true,i+1,right)+process(str,false,left,i-1)*process(str,false,i+1,right);
            }
        }
    }
    return res;

}
int num1(string express,bool desired){
    if(express.empty())return 0;

    if(!isValid(express))
        return 0;
    return process(express,desired,0,express.size()-1);
}

int num2(string express,bool desired){
    if(express.empty())return 0;
    if(!isValid(express))
        return 0;
    int n=express.size();
    vector<vector<int>> T(n,vector<int>(n));
    vector<vector<int>> F(n,vector<int>(n));
    T[0][0]=express[0]=='1'?1:0;
    F[0][0]=express[0]=='0'?1:0;
    for(int j=2;j2){
        T[j][j]=express[j]=='1'?1:0;
        F[j][j]=express[j]=='0'?1:0;
        for(int i=j-2;i>=0;i-=2){
            for(int k=i;k2){
                switch(express[k+1]){
            case '&':
                 T[i][j]+=T[i][k]*T[k+2][j];
                 F[i][j]+=F[i][k]*F[k+2][j]+F[i][k]*T[k+2][j]+T[i][k]*F[k+2][j];
                 break;
            case '|':
                T[i][j]+=T[i][k]*T[k+2][j]+F[i][k]*T[k+2][j]+T[i][k]*F[k+2][j];
                F[i][j]+=F[i][k]*F[k+2][j];
                break;
            case '^':
                T[i][j]+=T[i][k]*F[k+2][j]+F[i][k]*T[k+2][j];
                F[i][j]+=F[i][k]*F[k+2][j]+T[i][k]*T[k+2][j];
                break;
                }

            }
        }
    }
    return desired? T[0][n-1]:F[0][n-1];
}

int main()
{
    string express = "1^0&0|1&1^0&0^1|0|1&1";
    //string express="1^0|0|1";
    bool desired = false;
   // int res=num1(express,desired);
    int res2=num2(express,desired);
    cout << "Hello world!" <<"  "<return 0;
}

你可能感兴趣的:(C++,算法求索,IT生活——琐事)