-
Notifications
You must be signed in to change notification settings - Fork 0
/
Tree.h
94 lines (63 loc) · 3.07 KB
/
Tree.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//----------------------------------------------------------------
#pragma once
//----------------------------------------------------------------
#include <iostream>
#include <string>
#include <vector>
#include <unordered_set>
#include <unordered_map>
//----------------------------------------------------------------
#include "Macros.h"
//----------------------------------------------------------------
namespace Grammars {
//----------------------------------------------------------------
struct TreeNode {
// Default constructor
TreeNode()
:parent{ nullptr }, word{ std::string() }, depth{ 0 }, heuristic{ 0 } {}
// Constructor to initialize children
TreeNode(TreeNode* p, std::string w, unsigned int d, unsigned int h)
:parent{ p }, word{ w }, depth{ d }, heuristic{ h } {}
TreeNode* parent; // The parent node
std::string word; // The word on the current node
unsigned int depth; // The depth of the node in the tree
unsigned int heuristic; // The heuristic score
}; // of struct TreeNode
//----------------------------------------------------------------
struct FrontierNode {
// Constructor to add a new node to the frontier
FrontierNode(TreeNode* node) : n{ node }, next{ nullptr } {}
TreeNode* n; // The node that will be checked
FrontierNode* next; // Next node
}; // of struct FrontierNode
//----------------------------------------------------------------
// Get the first node that is in the frontier to check
// if it is the solution or to expand it
TreeNode* get_front(FrontierNode** frontierHead, FrontierNode** frontierTail);
// Add the new child to the back of the frontier
void add_to_back(FrontierNode** frontierHead, FrontierNode** frontierTail, TreeNode* child);
// Add the child in order in the frontier
void add_in_order(FrontierNode** frontierHead, FrontierNode** frontierTail, TreeNode* child);
// Prune any child that holds a word that is already on the tree
// or any child that holds a word that cannot generate the solution
bool prune(std::string finalWord, TreeNode* child,
const std::unordered_set<std::string>& wordSet,
const std::unordered_set<char>& terminalSymbols,
const std::unordered_set<char>& nonTerminalSymbols,
const size_t maxRuleGenLen);
// Generate new words using the provided rules
void generate_words(std::string word, int location,
std::unordered_map<char, std::vector<std::string>>& ruleMap,
int lastRuleIndex, std::vector<std::string>& words, size_t& wordsIndex);
// Generate children by applying the rules to theirs parent's word
void generate_children(TreeNode* node,
std::unordered_map<char, std::vector<std::string>> ruleMap,
std::vector<TreeNode*>& children,
const std::unordered_set<char>& nonTermSymbols);
// Clear the tree to avoid memory leaks
void clear_tree(FrontierNode* head);
// Print the solution to the screen
void show_solution(TreeNode* solutionNode, const std::unordered_set<char>& nonTermSymbols);
//----------------------------------------------------------------
} // of namespace Grammars
//----------------------------------------------------------------