题目要求:
给你两个字符串,其中一个是模式字符串pattern,一个是string字符串str。判断str字符串是否符合pattern字符串所表达的模式。比如:
pattern = "abba"
, str = "dog cat cat dog"
则返回true。
pattern = "abba"
, str = "dog cat cat fish"
则返回false。
pattern = "aaaa"
, str = "dog cat cat dog"
则返回false。
pattern = "abba"
, str = "dog dog dog dog"
则返回false。
注意:你可以假设patter和str里面全都是小写字母,并且str字符串是被几个空格分开的字符串。
解题思路:
若要判断str字符串是否符合pattern字符串的模式,首先要将str字符串进行分割,即把“dog cat cat dog”这样一个长的字符串分割为“dog”,“cat”,“cat”,“dog”这样四个短字符串。这样才能进行比较。程序中用一个vector容器来存放分割后的字符。定义一个string类型的word用来叠加字符。用一个for循环遍历str数组,当碰到空格字符时,就将word里面存放的字符存入vector中,同时令word等于空字符串。
程序如下:
vector<string> sstr;
string word("");
for(int i = 0;i< str.length();i++){
if(str[i]==' '){
sstr.push_back(word);
word="";
}
else
word+=str[i];
if(i==str.length()-1)
sstr.push_back(word);
}
然后定义两个无序容器map,用来存放对应关系,其中mp以pattern[i]的char作为键值,ms以sstr[i]的string作为键值。然后对mp和ms进行插入的过程中就可判断是否符合模式。
程序实现:
class Solution {
public:
bool wordPattern(string pattern,string str)
{
vector<string> sstr;
string word("");
for(int i = 0;i< str.length();i++){
if(str[i]==' '){
sstr.push_back(word);
word="";
}
else
word+=str[i];
if(i==str.length()-1)
sstr.push_back(word);
}
if(pattern.length()!=sstr.size()){
return false;
}//如果pattern字符串的长度与sstr容器的大小不等,显然str字符串不可能符合模式pattern。
unordered_map<char,string>mp;
unordered_map<string,char>ms;
for(int i=0;i<pattern.length();i++){
if(mp.find(pattern[i])==mp.end()&&ms.find(sstr[i])==ms.end()){
mp[pattern[i]]=sstr[i];
ms[sstr[i]]==pattern[i];
}//对mp和ms进行插入,如果在mp里面没有找到pattern[i],同时在ms里面也没有找到sstr[i],就说明这是一个组合,插入mp和ms中。
else if(mp.find(pattern[i])!=mp.end()&&ms.find(sstr[i])!=ms.end()){
if(mp[pattern[i]]!=sstr[i])
return false;
}//如果在mp里面找到了pattern[i],同时在ms里面也找到了sstr[i],那么如果这个组合不对应(比如“aba”和“dog cat cat”,在i=2的时 //候虽然a已经存在于mp中,
//cat也存在于ms中,但是a却没有对应dog,所以不符合),则返回false。
else return false;//其他两种情况,比如在mp里面找到了,ms里面却没找到,或者ms里面找到了,mp里面没找到。显然不可能符合. }
return true;
}
};
总结:
本来想定义一个map和一个set。用set来存放切割后的字符串,用map来存放对应关系(以char为键值)。这样就可以少定义一个map了,但是想了一下才发现set虽然可以完成find的功能,但是不能随机访问。
这次的做题的速度快了很多,碰到一些错误也能够很快的找到原因。熟能生巧,加油!