第一题:字符串与含有通用字符.*的字符串匹配问题
#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;
}