#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <unordered_map>
using namespace std;
class Trie{
public:
vector<Trie*> child;
unordered_map<int, int> umap; // Remaining characters -> # of words
Trie(){
this->child.resize(128, nullptr);
}
void insertWord(string word){
Trie *iter = this;
for(int i = 0;i < word.size(); i++){
int leftOver = word.size() - i;
iter->umap[leftOver] += 1;
if(iter->child[word[i]] == nullptr){
iter->child[word[i]] = new Trie();
}
iter = iter->child[word[i]];
}
iter->umap[0] += 1;
}
int findWords(string word, int remLen){
//cout << "\nword=" << word << " remlen=" << remLen << endl;
Trie *iter = this;
for(char c : word){
iter = iter->child[c];
if(iter == nullptr)
return 0;
}
int numWord = iter->umap[remLen];
//cout << "numWord=" << numWord << endl;
return numWord;
}
bool findQuery(string word){
string str = "";
int remLen = 0;
for(int i = 0;i < word.size(); i++){
char c = word[i];
if(isdigit(c)){
while(i < word.size()){
char c = word[i];
if(!(isdigit(c)))
break;
remLen *= 10;
remLen += (c - '0');
i++;
}
break;
} else {
str += c;
}
}
return this->findWords(str, remLen) == 1;
}
};
class Solution{
public:
bool run_query(vector<string>& words, string query){
Trie *trie = new Trie();
for(string word : words){
trie->insertWord(word);
}
return trie->findQuery(query);
}
};
int main(){
vector<string> words = {"ball", "cat", "baby", "cater"};
cout << "words=";
for(string word : words){
cout << word << ",";
}
cout << endl;
vector<string> all_queries = {"ca1", "cat", "ba2", "c4", "3", "4"};
for(string query: all_queries){
bool queryExists = Solution().run_query(words, query);
cout << "query word=" << query << " unique exists=" << queryExists << endl;
}
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8bWFwPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dW5vcmRlcmVkX21hcD4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7CmNsYXNzIFRyaWV7CglwdWJsaWM6CgkJdmVjdG9yPFRyaWUqPiBjaGlsZDsKCQl1bm9yZGVyZWRfbWFwPGludCwgaW50PiB1bWFwOyAvLyBSZW1haW5pbmcgY2hhcmFjdGVycyAtPiAjIG9mIHdvcmRzCgoJCVRyaWUoKXsKCQkJdGhpcy0+Y2hpbGQucmVzaXplKDEyOCwgbnVsbHB0cik7CgkJfQoJCXZvaWQgaW5zZXJ0V29yZChzdHJpbmcgd29yZCl7CgkJCVRyaWUgKml0ZXIgPSB0aGlzOwoJCQlmb3IoaW50IGkgPSAwO2kgPCB3b3JkLnNpemUoKTsgaSsrKXsKCQkJCWludCBsZWZ0T3ZlciA9IHdvcmQuc2l6ZSgpIC0gaTsKCQkJCWl0ZXItPnVtYXBbbGVmdE92ZXJdICs9IDE7CgkJCQlpZihpdGVyLT5jaGlsZFt3b3JkW2ldXSA9PSBudWxscHRyKXsKCQkJCQlpdGVyLT5jaGlsZFt3b3JkW2ldXSA9IG5ldyBUcmllKCk7CgkJCQl9CgkJCQlpdGVyID0gaXRlci0+Y2hpbGRbd29yZFtpXV07CgkJCX0KCQkJaXRlci0+dW1hcFswXSArPSAxOwoJCX0KCQlpbnQgZmluZFdvcmRzKHN0cmluZyB3b3JkLCBpbnQgcmVtTGVuKXsKCQkJLy9jb3V0IDw8ICJcbndvcmQ9IiA8PCB3b3JkIDw8ICIgcmVtbGVuPSIgPDwgcmVtTGVuIDw8IGVuZGw7CgkJCVRyaWUgKml0ZXIgPSB0aGlzOwoJCQlmb3IoY2hhciBjIDogd29yZCl7CgkJCQlpdGVyID0gaXRlci0+Y2hpbGRbY107CgkJCQlpZihpdGVyID09IG51bGxwdHIpCgkJCQkJcmV0dXJuIDA7CgkJCX0KCQkJaW50IG51bVdvcmQgPSBpdGVyLT51bWFwW3JlbUxlbl07CgkJCS8vY291dCA8PCAibnVtV29yZD0iIDw8IG51bVdvcmQgPDwgZW5kbDsKCQkJcmV0dXJuIG51bVdvcmQ7CgkJfQoJCWJvb2wgZmluZFF1ZXJ5KHN0cmluZyB3b3JkKXsKCQkJc3RyaW5nIHN0ciA9ICIiOwoJCQlpbnQgcmVtTGVuID0gMDsKCQkJZm9yKGludCBpID0gMDtpIDwgd29yZC5zaXplKCk7IGkrKyl7CgkJCQljaGFyIGMgPSB3b3JkW2ldOwoJCQkJaWYoaXNkaWdpdChjKSl7CgkJCQkJd2hpbGUoaSA8IHdvcmQuc2l6ZSgpKXsKCQkJCQkJY2hhciBjID0gd29yZFtpXTsKCQkJCQkJaWYoIShpc2RpZ2l0KGMpKSkKCQkJCQkJCWJyZWFrOwoJCQkJCQlyZW1MZW4gKj0gMTA7CgkJCQkJCXJlbUxlbiArPSAoYyAtICcwJyk7CgkJCQkJCWkrKzsKCQkJCQl9CgkJCQkJYnJlYWs7CgkJCQl9IGVsc2UgewoJCQkJCXN0ciArPSBjOwoJCQkJfQoJCQl9CgkJCXJldHVybiB0aGlzLT5maW5kV29yZHMoc3RyLCByZW1MZW4pID09IDE7CgkJfQp9OwpjbGFzcyBTb2x1dGlvbnsKCXB1YmxpYzoKCQlib29sIHJ1bl9xdWVyeSh2ZWN0b3I8c3RyaW5nPiYgd29yZHMsIHN0cmluZyBxdWVyeSl7CgkJCVRyaWUgKnRyaWUgPSBuZXcgVHJpZSgpOwoJCQlmb3Ioc3RyaW5nIHdvcmQgOiB3b3Jkcyl7CgkJCQl0cmllLT5pbnNlcnRXb3JkKHdvcmQpOwoJCQl9CgkJCXJldHVybiB0cmllLT5maW5kUXVlcnkocXVlcnkpOwoJCX0KfTsKaW50IG1haW4oKXsKCXZlY3RvcjxzdHJpbmc+IHdvcmRzID0geyJiYWxsIiwgImNhdCIsICJiYWJ5IiwgImNhdGVyIn07Cgljb3V0IDw8ICJ3b3Jkcz0iOwoJZm9yKHN0cmluZyB3b3JkIDogd29yZHMpewoJCWNvdXQgPDwgd29yZCA8PCAiLCI7Cgl9Cgljb3V0IDw8IGVuZGw7Cgl2ZWN0b3I8c3RyaW5nPiBhbGxfcXVlcmllcyA9IHsiY2ExIiwgImNhdCIsICJiYTIiLCAiYzQiLCAiMyIsICI0In07Cglmb3Ioc3RyaW5nIHF1ZXJ5OiBhbGxfcXVlcmllcyl7CgkJYm9vbCBxdWVyeUV4aXN0cyA9IFNvbHV0aW9uKCkucnVuX3F1ZXJ5KHdvcmRzLCBxdWVyeSk7CgkJY291dCA8PCAicXVlcnkgd29yZD0iIDw8IHF1ZXJ5IDw8ICIgdW5pcXVlIGV4aXN0cz0iIDw8IHF1ZXJ5RXhpc3RzIDw8IGVuZGw7Cgl9Cn0=