字符串函数的熟练使用(模拟)
思路:
- 查找是否存在“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; } }