Module 12: Pattern Hash

This commit is contained in:
David Doblas Jiménez 2021-08-05 20:23:12 +02:00
parent a8c5c425be
commit b27c93dfd2

58
a.c
View File

@ -22,30 +22,29 @@ string ToUpper(string s) {
struct Word {
Word() {} // default empty constructor
Word(string s) : word(s) {} // standard way of initialization
int len() const { return word.length(); }
string word;
};
typedef vector<Word> Words;
typedef unordered_map<string, Word> WordMap; // hash-table from stl
typedef vector<Word*> Words; // will store pointers to Words (will not delete by itself)
typedef unordered_map<string, Words> WordMap; // hash-table from stl
// --------------------------------------------------------------------------------
//-Library
class Library {
public:
Library() {} // hash-tables are automatically initialized
~Library() { // destructor of the pointers (instead of the unique pointer)
for (Word* w : words_) {
delete w;
}
}
void FindWord(const string& s) const { // references are prefered instead of copies
int len = s.length(); // cache the length to avoid multiple calls
for (const Word& w : words_) { // references are prefered instead of copies
string temp = w.word;
if (len == temp.length()) {
for (int i=0; i<len; i++) {
if (s[i] == '-') {
temp[i] = '-';
}
}
if (s == temp) {
cout << w.word << "\n"; // print the original word
}
auto it = word_map_.find(s);
if (it != word_map_.end()) {
for (const Word* w : it->second) {
cout << " " << w->word;
}
cout << "\n";
}
}
bool IsWord(string s) const {
@ -60,8 +59,8 @@ public:
void ComputeStats() {
assert(counts_.empty());
counts_.resize(18);
for (Word w : words_) {
int len = w.word.length();
for (const Word* w : words_) { // Word is a pointer!
int len = w->word.length(); // w is not an actual object (it's a pointer)
if (len < 18) {
counts_[len]++;
}
@ -75,7 +74,23 @@ public:
}
string GetWord(int i) const {
assert(i >= 0 && i < words_.size());
return words_[i].word;
return words_[i]->word;
}
void CreatePatternHash(Word* w) {
int len = w->len();
int num_patterns = 1 << len; // create 2^len patterns
// cout << "PATTERN HASH on " << w->word << "\n";
for (int i=0; i<num_patterns; i++) {
// cout << " " << i << "\n";
string temp = w->word;
for (int j=0; j<len; j++) {
if ((i >> j) & 1) { // get every bit and check if it's 1
temp[j] = '-';
}
}
// cout << " " << temp << "\n";
word_map_[temp].push_back(w);
}
}
void ReadFromFile(string filename) {
ifstream f;
@ -90,8 +105,9 @@ public:
if (line[len - 1] == '\r') {
line = line.substr(0, len - 1);
}
words_.push_back(Word(line));
word_map_[line] = Word(line); // create entry for the hash-table
Word* w = new Word(line);
words_.push_back(w); // Word would be allocated on the heap
CreatePatternHash(w);
}
}
cout << "Read " << words_.size() << " words from file '"
@ -104,8 +120,8 @@ public:
}
private: // _ is used to indicate privacy
Words words_;
WordMap word_map_;
Words words_; // master vector of words
WordMap word_map_; // pattern hash
vector<int> counts_;
};