一. 题目描述
Given a pattern and a string str, find if str follows the same pattern.
Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in str.
Examples:
pattern = "abba"
, str = "dog cat cat dog"
should return true
.
pattern = "abba"
, str = "dog cat cat fish"
should return false
.
pattern = "aaaa"
, str = "dog cat cat dog"
should return false
.
pattern = "abba"
, str = "dog dog dog dog"
should return false
.
Notes:
You may assume pattern contains only lowercase letters, and str contains lowercase letters separated by a single space.
二. 题目分析
题目的大意是,给出一组模式(pattern)和一个字符串(str),判断字符串是否与模式相匹配,并给出了几个例子。
题目提到,模式pattern仅由小写字母构成,而字符串str中每个单词均被单个空格字符隔开,且字符串中每个单词都由小写字母构成(这种设定可以少考虑很多边界条件);模式pattern和字符串str的前后都不包含多余的空格;且模式pattern中的每个字母必须匹配一个字符串str中长度至少为1的单词。
容易想到的是,使用Map来解决这个问题。
于是乎,定义一个map
,每遇到一个新的模式,以模式为key
,将对应的单词存入map
;遇到map
里已有的模式,检查当前str
的单词是否与map
记载模式所对应的value值相同,只要出现不同,直接返回false
。
这种判断方法可以解决:pattern = "abba"
, str = "dog cat cat fish"
这种情况。
但是,只使用一个map无法判断这种情况:pattern = "abba"
, str = "dog dog dog dog"
,一开始a作为一个新模式,被存入
map
,到了第二次迭代,b作为一个新模式,也被存入
map
,dog
被分配到两个不同的模式,显然这是不对的。
为了解决这个问题,需要两个map
。另一个map2
用于记载单词与模式的对应关系。
总的来说,map用于记载模式到单词的对应关系,但可能出现多个模式对应到同个单词的情形。
而map2用于记载单词到模式的对应关系,在判断中同时加入对两个map的判断,才可以分辨所有情况。
三. 示例代码
class Solution {
public:
bool wordPattern(string pattern, string str) {
unordered_map<char, string=""> map; // 作用是防止出现单词不同但模式相同的情况
unordered_map<string, char=""> map2; // 作用是防止出现模式不同但单词同名的情况
vector<string> vec; // 存放逐个单词
// 以下操作分割str为多个单词
for (int i = 0, j = 0; i < str.size(); ++i)
{
if (i == str.size() - 1)
{
string temp = str.substr(j, i - j + 1);
vec.push_back(temp);
}
if (str[i] == ' ')
{
string temp = str.substr(j, i - j);
vec.push_back(temp);
j = i + 1;
}
}
if (pattern.size() != vec.size()) return false;
for (int i = 0; i < pattern.size(); ++i)
{
// 当前模式未出现,且对应的单词也未出现,才将键值对存入表
if (map.find(pattern[i]) == map.end() && map2.find(vec[i]) == map2.end())
{
map.insert(make_pair(pattern[i], vec[i]));
map2.insert(make_pair(vec[i], pattern[i]));
}
else if (map[pattern[i]] != vec[i])
return false;
}
return true;
}
};