#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <sstream>
/*
s1 = "red blue blue red red yellow"
s2 = "abbaac"
This would match because they have the same pattern.
*/
typedef size_t hash_type;
typedef std::map<hash_type,size_t> hash_map;
typedef std::vector<std::string> wordlist;
//taken from http://stackoverflow.com/a/8317622/13760
#define A 54059 /* a prime */
#define B 76963 /* another prime */
#define C 86969 /* yet another prime */
size_t hash(const char* s)
{
size_t h = 31 /* also prime */;
while (*s) {
h = (h * A) ^ (s[0] * B);
s++;
}
return h; // or return h % C;
}
#undef A
#undef B
#undef C
size_t ordered_symbol( hash_map &h, std::string const& word )
{
hash_type word_hash = hash(word.c_str());
if(h.find(word_hash)==h.end())
{
size_t const sequence = h.size();
h[word_hash] = sequence;
return sequence;
}
return h[word_hash];
}
wordlist create_wordlist( std::string const& str )
{
if(str.find_first_of(' ') != std::string::npos)
{
wordlist w1;
std::stringstream sstr(str);
std::string s;
while(sstr>>s)
w1.push_back(s);
return w1;
}
wordlist w2;
for(size_t i=0; i!=str.length();++i)
{
std::string s;
s.append(1,str[i]);
w2.push_back(s);
}
return w2;
}
bool pattern_matches( std::string const& s1, std::string const& s2 )
{
wordlist const w1 = create_wordlist(s1);
wordlist const w2 = create_wordlist(s2);
if(w1.size()!=w2.size())
return false;
hash_map h1,h2;
for( size_t i = 0; i!=w1.size(); ++i)
if(ordered_symbol(h1,w1[i])!=ordered_symbol(h2,w2[i]))
return false;
return true;
}
void test( std::string const& s1, std::string const& s2 )
{
std::cout<<"["<<s1<<"] "
<<(pattern_matches(s1,s2)? "<==>" : "<=!=>")
<<"["<<s2<<"]\n";
}
int main()
{
test("red blue blue red red yellow","abbaac");
test("red blue blue red red yellow","first second second first first third");
test("abbaac","12211g");
test("abbaac","red blue blue red red yellow");
test("abbgac","red blue blue red red yellow");
return 0;
}