目录
字符串函数的熟练使用(模拟)
别看题目很长,其实就是简单的斗地主,比较两手牌哪边大而已;
思路:
- 查找是否存在“xx”字符
line.find("xx")!=string::npos
- substr查找下标区间为左闭右开[x,y)
- 查找一段字符串中有多少个字符“x”
count(car1.begin(),car1.end(),'x')
#include <iostream>
#include<algorithm>
using namespace std;
string findmax(string line)
{
if(line.find("joker JOKER")!=string::npos)//如果有王炸直接输出
return "joker JOKER";
int dash=line.find('-');
//将两手牌分开
string car1=line.substr(0,dash);
string car2=line.substr(dash+1);
//获取两手牌张数
int sum1=count(car1.begin(),car1.end(),' ')+1;//牌数等于空格数+1
int sum2=count(car2.begin(),car2.end(),' ')+1;
//取两手牌各自第一张牌
string car1_first=car1.substr(0,car1.find(' '));
string car2_first=car2.substr(0,car1.find(' '));
if(sum1==sum2)//张数相同,则类型相同
{
string str="345678910JQKA2jokerJOKER";//大小顺序
if(str.find(car1_first)>str.find(car2_first)) return car1;
return car2;
}
if(sum1==4) return car1; //是炸弹肯定大
else if(sum2==4) return car2;
return "ERROR";
}
int main() {
string line,res;
while(getline(cin,line))//输入带空格字符串
{
res=findmax(line);
cout<<res<<endl;
}
return 0;
}
双指针+模拟+回溯
思路:
本题可以通过递归求解。从前向后一次匹配,遇到相同字符,都向后移动一个字符,如果通配符遇到
"?"
,则不需匹配,自动跳过一个字符,如果通配符遇到
"*"
,则可以匹配任意多个字符,包括
0
个,此时可以有三种
选择,
- 匹配0个,通配符向后移动一个字符,字符串不动。
- 匹配1个,通配符和字符串都向后移动一个 字符。
- 匹配多个,通配符不动,字符串向后移动一个字符。
- 递归的终止条件:通配符或者字符串遇到'\0'。当他们同时结束。
isdigit(a);//判断是否为数字字符
isalpha(a);//判断是否为英文字符
tolower(a);//忽略字符大小写
#include <iostream>
using namespace std;
bool match(const char*p,const char*s)
{
if(*p=='\0'&& *s=='\0') return true;//同时结束,符合要求
if(*p=='\0'||*s=='\0') return false;//不同时,说明有字符不匹配
if(*p=='?')
{
//?只能匹配数字和字符,如果当前遇到了?,又遇到了其他字符,返回false
if(!isdigit(*s)&&!isalpha(*s)) return false;
return match(p+1,s+1);
}
else if(*p=='*')
{
while(*p=='*') p++; p--;//遇到连续多个*号,只有一个管用(否则超时)
// 遇到*号,匹配0个(str不挪动),1个(两者都向前挪动一个字符)或多个(str向前挪动一个字符)
return match(p+1,s) || match(p+1,s+1) || match(p,s+1);//用或,一个符合即可
}
else if(tolower(*p)==tolower(*s)) return match(p+1,s+1);
return false;
}
int main() {
string pattern,str;
while(cin>>pattern>>str)
{
bool ret= match(pattern.c_str(),str.c_str());
if(ret) cout<<"true"<<endl;
else cout<<"false"<<endl;
}
}