Description
- Pseudocode: Understand the strategy provided for TrieAutoComplete. State the algorithm for the functions precisely using numbered steps that follow the pseudocode conventions that we use. Provide an approximate efficiency analysis by filling the table given below, for your algorithm.
Add
- Pseudocode:
- if word is null
- throw an exception
- if weight < 0
- throw an exception
- char character = “”
- Node temp = root node of the tree
- For a to word.length
- Character = the character at index a
- Node next = the child node of temp with the
character character
- If next is null
- Initialize next with the index of the character, parent temp, and given weight
- Add the new child to tree
- If the weight > temp subtree max weight
- temp subtree max weight = weight
- Point temp to next
- Set temp node word value
- Set temp node weight
- Set temp node to that of a word
- Complexity analysis:
Step # | Complexity stated as O(_) |
1 | O(1) |
2 | O(1) |
3 | O(1) |
4 | O(1) |
5 | O(1) |
6 | O(1) |
7 | O(n) |
8 | O(n) |
9 | O(n) |
10 | O(n) |
11 | O(n) |
12 | O(n) |
13 | O(n) |
14 | O(n) |
15 | O(n) |
16 | O(1) |
17 | O(1) |
18 | O(1) |
Complexity of the algorithm = O(n)
topMatch
- Pseudocode:
- if prefix is null
- throw an exception
- Boolean matchFound = true
- char character = “”
- Node temp = root node of the tree
- string emptyString = “”
- string bestMatchFound = “”
- priorityQueue = new priority queue of nodes using
a reverse weight comparator
- for a to prefix.length
- character = the character in the word at index a
- if a child of temp contains the value of character
- temp points to that child
- else
- matchFound = false
- break
16 if matchFound is false
- return emptyString
- while temp’s subtree max weight > temp’s weight and
temp is a word
- for every node within temp’s children
- add that node into priorityQueue
- point temp to the head of the queue and then remove the element from the queue
- bestMatchFound = word value of temp node
- return bestMatchFound
- Complexity analysis:
Step # | Complexity stated as O(_) |
1 | O(1) |
2 | O(1) |
3 | O(1) |
4 | O(1) |
5 | O(1) |
6 | O(1) |
7 | O(1) |
8 | O(1) |
9 | O(n) |
10 | O(n) |
11 | O(n) |
12 | O(n) |
13 | O(n) |
14 | O(n) |
15 | O(n) |
16 | O(1) |
17 | O(1) |
18 | O(n) |
19 | O(n²) |
20 | O(n²) |
21 | O(n) |
22 | O(1) |
23 | O(1) |
Complexity of the algorithm = O(n²)
topMatches
- Pseudocode:
- if prefix is null
- throw an exception
- char character = “”
- Node temp = root of the tree
- wordList = new ArrayList of Nodes
- output = new ArrayList of Strings
- noWordsList = new ArrayList of Strings
- priorityQueue = new PriorityQueue of Nodes
- for a to prefix.length
- character = the character in the word at the index a
- temp points to the child with the value of i
- if temp is null
- return noWordsList
- if priorityQueue is not null
- add temp to priorityQueue
- while priorityQueue is not empty
- if the size of wordList >= k
- sort wordList in descending order of the values
- break
- set temp to point to the head of the queue and then remove the element from the queue
- if temp is a word
- add temp to wordList
- for each node within temp nodes children
- add the node into priorityQueue
- for b to the smallest value between k and wordList’s size
- add the word that is located at b to output
- return output
- Complexity analysis:
Step # | Complexity stated as O(_) |
1 | O(1) |
2 | O(1) |
3 | O(1) |
4 | O(1) |
5 | O(1) |
6 | O(1) |
7 | O(1) |
8 | O(1) |
9 | O(n) |
10 | O(n) |
11 | O(n) |
12 | O(n) |
13 | O(n) |
14 | O(1) |
15 | O(1) |
16 | O(n) |
17 | O(n) |
18 | O(nlogn) |
19 | O(1) |
20 | O(n) |
21 | O(n) |
22 | O(n) |
23 | O(n²) |
24 | O(n²) |
25 | O(n) |
26 | O(n) |
27 | O(1) |
Complexity of the algorithm = O(n²)
2.Testing: Complete your test cases to test the TrieAutoComplete functions based upon the criteria mentioned below.
Test of correctness:
Assuming the trie already contains the terms {”ape, 6”, ”app, 4”, ”ban, 2”, ”bat, 3”, ”bee, 5”, ”car, 7”, ”cat, 1”}, you would expect results based on the following table:
Query | k | Result |
”” | 8 | {”car”, ”ape”, ”bee”, ”app”, ”bat”, ”ban”, ”cat”} |
”” | 1 | {”car”} |
”” | 2 | {”car”, ”ape”} |
”” | 3 | {”car”, ”ape”, ”bee”} |
”a” | 1 | {”ape”} |
”ap” | 1 | {”ape”} |
”b” | 2 | {”bee”, ”bat”} |
”ba” | 2 | {”bee”, ”bat”} |
”d” | 100 | {} |
**passed all test cases**
3.Analysis: Answer the following questions. Use data wherever possible to justify your answers, and keep explanations brief but accurate:
- What is the order of growth (big-Oh) of the number of compares (in the worst case) that each of the operations in the Autocompletor data type make?
- Add: O(n)
- topMatch: O(n²)
- topMatches: O(n²)
- How does the runtime of topMatches() vary with k, assuming a fixed prefix and set of terms? Provide answers for BruteAutocomplete and TrieAutocomplete. Justify your answer, with both data and algorithmic analysis.
- How does increasing the size of the source and increasing the size of the prefix argument affect the runtime of topMatch and topMatches? (Tip: Benchmark each implementation using fourletterwords.txt, which has all four-letter combinations from aaaa to zzzz, and fourletterwordshalf.txt, which has all four-letter word combinations from aaaa to mzzz. These datasets provide a very clean distribution of words and an exact 1-to-2 ratio of words in source files.)
- Graphical Analysis: Provide a graphical analysis by comparing the following:
- The big-Oh for TrieAutoComplete after analyzing the pseudocode and big-Oh for TrieAutoComplete after the implementation.
- Compare the TrieAutoComplete with BruteAutoComplete and BinarySearchAutoComplete.
- According to the data shown above, it is apparent that Trie is far more efficient than that of Brute and Binary.