#include <iostream>
#include <vector>
#include <string>
#include <unordered_set>
#include <unordered_map>
#include <stdexcept>
using namespace std;
class WordFinder {
public:
struct Node {
char c;
unordered_map<char, Node*> children;
bool end = false;
Node() : c(0), end(false) {}
Node(char ch) : c(ch), end(false) {}
// In a complete solution, you'd want to add a destructor to free children.
~Node() {
for (auto &entry : children) {
delete entry.second;
}
}
};
Node* root;
vector<char> charC;
// Constructor: builds the trie from a list of words and copies the search characters.
WordFinder(vector<string>& words, vector<char>& c) {
root = new Node();
charC = c;
for (const string &w : words) {
insert(w);
}
}
// Destructor to free allocated memory.
~WordFinder() {
delete root;
}
/** Inserts a word into the trie. */
void insert(const string &word) {
Node* temp = root;
for (char a : word) {
// Use unordered_map to check for the child.
if (temp->children.find(a) == temp->children.end()) {
temp->children[a] = new Node(a);
}
temp = temp->children[a];
}
temp->end = true;
}
// Recursive helper function to find words given available characters.
void find_r(vector<char>& chars, Node* cn, string curr_word, unordered_set<string>& res) {
if (cn == nullptr) return;
if (cn->end) {
res.insert(curr_word);
}
for (size_t i = 0; i < chars.size(); i++) {
if (chars[i] == '*') continue;
char temp = chars[i];
// Mark the character as used.
chars[i] = '*';
// Only proceed if there is a valid child.
if (cn->children.find(temp) != cn->children.end()) {
find_r(chars, cn->children[temp], curr_word + temp, res);
}
// Restore the character.
chars[i] = temp;
}
}
// Public function to initiate the word finding process.
unordered_set<string> find() {
unordered_set<string> res;
find_r(charC, root, "", res);
return res;
}
};
int main() {
vector<string> words = {"word", "words", "wood", "order"};
vector<char> c = {'o','r','s','d','o','w','e'};
WordFinder wf(words, c);
unordered_set<string> res = wf.find();
for (const auto& r : res) {
cout << r << endl;
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dW5vcmRlcmVkX3NldD4KI2luY2x1ZGUgPHVub3JkZXJlZF9tYXA+CiNpbmNsdWRlIDxzdGRleGNlcHQ+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgpjbGFzcyBXb3JkRmluZGVyIHsKcHVibGljOgogICAgc3RydWN0IE5vZGUgewogICAgICAgIGNoYXIgYzsKICAgICAgICB1bm9yZGVyZWRfbWFwPGNoYXIsIE5vZGUqPiBjaGlsZHJlbjsKICAgICAgICBib29sIGVuZCA9IGZhbHNlOwogICAgICAgIAogICAgICAgIE5vZGUoKSA6IGMoMCksIGVuZChmYWxzZSkge30KICAgICAgICBOb2RlKGNoYXIgY2gpIDogYyhjaCksIGVuZChmYWxzZSkge30KICAgICAgICAKICAgICAgICAvLyBJbiBhIGNvbXBsZXRlIHNvbHV0aW9uLCB5b3UnZCB3YW50IHRvIGFkZCBhIGRlc3RydWN0b3IgdG8gZnJlZSBjaGlsZHJlbi4KICAgICAgICB+Tm9kZSgpIHsKICAgICAgICAgICAgZm9yIChhdXRvICZlbnRyeSA6IGNoaWxkcmVuKSB7CiAgICAgICAgICAgICAgICBkZWxldGUgZW50cnkuc2Vjb25kOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfTsKCiAgICBOb2RlKiByb290OwogICAgdmVjdG9yPGNoYXI+IGNoYXJDOwoKICAgIC8vIENvbnN0cnVjdG9yOiBidWlsZHMgdGhlIHRyaWUgZnJvbSBhIGxpc3Qgb2Ygd29yZHMgYW5kIGNvcGllcyB0aGUgc2VhcmNoIGNoYXJhY3RlcnMuCiAgICBXb3JkRmluZGVyKHZlY3RvcjxzdHJpbmc+JiB3b3JkcywgdmVjdG9yPGNoYXI+JiBjKSB7CiAgICAgICAgcm9vdCA9IG5ldyBOb2RlKCk7CiAgICAgICAgY2hhckMgPSBjOwogICAgICAgIGZvciAoY29uc3Qgc3RyaW5nICZ3IDogd29yZHMpIHsKICAgICAgICAgICAgaW5zZXJ0KHcpOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBEZXN0cnVjdG9yIHRvIGZyZWUgYWxsb2NhdGVkIG1lbW9yeS4KICAgIH5Xb3JkRmluZGVyKCkgewogICAgICAgIGRlbGV0ZSByb290OwogICAgfQogICAgCiAgICAvKiogSW5zZXJ0cyBhIHdvcmQgaW50byB0aGUgdHJpZS4gKi8KICAgIHZvaWQgaW5zZXJ0KGNvbnN0IHN0cmluZyAmd29yZCkgewogICAgICAgIE5vZGUqIHRlbXAgPSByb290OwogICAgICAgIGZvciAoY2hhciBhIDogd29yZCkgewogICAgICAgICAgICAvLyBVc2UgdW5vcmRlcmVkX21hcCB0byBjaGVjayBmb3IgdGhlIGNoaWxkLgogICAgICAgICAgICBpZiAodGVtcC0+Y2hpbGRyZW4uZmluZChhKSA9PSB0ZW1wLT5jaGlsZHJlbi5lbmQoKSkgewogICAgICAgICAgICAgICAgdGVtcC0+Y2hpbGRyZW5bYV0gPSBuZXcgTm9kZShhKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0ZW1wID0gdGVtcC0+Y2hpbGRyZW5bYV07CiAgICAgICAgfQogICAgICAgIHRlbXAtPmVuZCA9IHRydWU7CiAgICB9CgogICAgLy8gUmVjdXJzaXZlIGhlbHBlciBmdW5jdGlvbiB0byBmaW5kIHdvcmRzIGdpdmVuIGF2YWlsYWJsZSBjaGFyYWN0ZXJzLgogICAgdm9pZCBmaW5kX3IodmVjdG9yPGNoYXI+JiBjaGFycywgTm9kZSogY24sIHN0cmluZyBjdXJyX3dvcmQsIHVub3JkZXJlZF9zZXQ8c3RyaW5nPiYgcmVzKSB7CiAgICAgICAgaWYgKGNuID09IG51bGxwdHIpIHJldHVybjsKICAgICAgICBpZiAoY24tPmVuZCkgewogICAgICAgICAgICByZXMuaW5zZXJ0KGN1cnJfd29yZCk7CiAgICAgICAgfQogICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgY2hhcnMuc2l6ZSgpOyBpKyspIHsKICAgICAgICAgICAgaWYgKGNoYXJzW2ldID09ICcqJykgY29udGludWU7CiAgICAgICAgICAgIGNoYXIgdGVtcCA9IGNoYXJzW2ldOwogICAgICAgICAgICAvLyBNYXJrIHRoZSBjaGFyYWN0ZXIgYXMgdXNlZC4KICAgICAgICAgICAgY2hhcnNbaV0gPSAnKic7CiAgICAgICAgICAgIC8vIE9ubHkgcHJvY2VlZCBpZiB0aGVyZSBpcyBhIHZhbGlkIGNoaWxkLgogICAgICAgICAgICBpZiAoY24tPmNoaWxkcmVuLmZpbmQodGVtcCkgIT0gY24tPmNoaWxkcmVuLmVuZCgpKSB7CiAgICAgICAgICAgICAgICBmaW5kX3IoY2hhcnMsIGNuLT5jaGlsZHJlblt0ZW1wXSwgY3Vycl93b3JkICsgdGVtcCwgcmVzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBSZXN0b3JlIHRoZSBjaGFyYWN0ZXIuCiAgICAgICAgICAgIGNoYXJzW2ldID0gdGVtcDsKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8vIFB1YmxpYyBmdW5jdGlvbiB0byBpbml0aWF0ZSB0aGUgd29yZCBmaW5kaW5nIHByb2Nlc3MuCiAgICB1bm9yZGVyZWRfc2V0PHN0cmluZz4gZmluZCgpIHsKICAgICAgICB1bm9yZGVyZWRfc2V0PHN0cmluZz4gcmVzOwogICAgICAgIGZpbmRfcihjaGFyQywgcm9vdCwgIiIsIHJlcyk7CiAgICAgICAgcmV0dXJuIHJlczsKICAgIH0KfTsKCmludCBtYWluKCkgewogICAgdmVjdG9yPHN0cmluZz4gd29yZHMgPSB7IndvcmQiLCAid29yZHMiLCAid29vZCIsICJvcmRlciJ9OwogICAgdmVjdG9yPGNoYXI+IGMgPSB7J28nLCdyJywncycsJ2QnLCdvJywndycsJ2UnfTsKICAgIFdvcmRGaW5kZXIgd2Yod29yZHMsIGMpOwogICAgdW5vcmRlcmVkX3NldDxzdHJpbmc+IHJlcyA9IHdmLmZpbmQoKTsKICAgIGZvciAoY29uc3QgYXV0byYgciA6IHJlcykgewogICAgICAgIGNvdXQgPDwgciA8PCBlbmRsOwogICAgfQogICAgcmV0dXJuIDA7Cn0K