BackTracking.
#include <string>
#include <vector>
#include <unordered_map>
#include <iostream>
using namespace std;
/*
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 substring in str.
Example:
1 Pattern: "abab", str = "redblueredblue", should return true;
2 Pattern: "aaaa", str = "asdasdasdasd" should return true;
3 Pattern: "aabb", str = "xyzabcxyzabc" should return false;
Note: You may assume both pattern and str contains only lowercase letters.
*/
bool wordPattern(string pattern, int i, string str, int j, unordered_map<string, int>& st, unordered_map<char, int>& pat) {
if(i == pattern.size() && j == str.size()) return true;
if(i == pattern.size() || j == str.size()) return false;
char c = pattern[i];
for(int k = 1; k <= str.size() - j; ++k) {
if(pat[c] == st[str.substr(j, k)]) {
pat[c]++;
st[str.substr(j, k)]++;
if(wordPattern(pattern, i + 1, str, j + k, st, pat)) return true;
pat[c]--;
st[str.substr(j, k)]--;
}
}
return false;
}
bool wordPattern(string pattern, string str) {
unordered_map<string, int> st;
unordered_map<char, int> pat;
return wordPattern(pattern, 0, str, 0, st, pat);
}
int main(void) {
string pattern_0 = "abab";
string str_0 = "redblueredblue";
cout << wordPattern(pattern_0, str_0) << endl;
string pattern_1 = "aaaa";
string str_1 = "asdasdasdasd";
cout << wordPattern(pattern_1, str_1) << endl;
string pattern_2 = "aabb";
string str_2 = "xyzabcxyzabc";
cout << wordPattern(pattern_2, str_2) << endl;
string pattern_3 = "aabb";
string str_3 = "aabbcc";
cout << wordPattern(pattern_3, str_3) << endl;
}