DSA-Assignments

Log | Files | Refs | README

commit 1422a324e94d1ccb164b44a7e71466f41907985a
parent dc1045353d9674206bf4256e37e0649fc5b81d2d
Author: TranLili <tranlili96@gmail.com>
Date:   Wed,  6 Dec 2023 20:32:32 +0100

Merge branch 'master' of https://github.com/LindholmLabs/DSA-Assignments

Diffstat:
MProblem2/Problem2.cpp | 60+++++++++++++++++++++++++++++++++++++++++++++++++++++-------
MProblem3/Problem3.cpp | 201++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
2 files changed, 192 insertions(+), 69 deletions(-)

diff --git a/Problem2/Problem2.cpp b/Problem2/Problem2.cpp @@ -17,10 +17,12 @@ private: vector<int>* adj; public: Graph(int V); - void addEdge(int v, int w); + void addEdge(int v, int w); //v == Source node, w == Destintaion node bool isEdge(int v, int w); int getNumNodes(); void printGraph(); + bool BFS(int v, int w, int dist[]); + void printShortPath(int v, int w); }; Graph::Graph(int V) { @@ -30,6 +32,7 @@ Graph::Graph(int V) { void Graph::addEdge(int v, int w) { adj[v].push_back(w); + adj[w].push_back(v); } bool Graph::isEdge(int v, int w) { @@ -50,12 +53,49 @@ void Graph::printGraph() { for (int v = 0; v < V; ++v) { cout << "\nAdjacency list of node " << v << "\n head "; vector<int>::iterator i; - for (i = adj[v].begin(); - i != adj[v].end(); ++i) { + for (i = adj[v].begin(); i != adj[v].end(); ++i) { cout << "-> " << *i << " "; } } } +bool Graph::BFS(int v, int w, int dist[]) +{ + vector<bool> visited; + visited.resize(V, false); + + list<int> queue; + + for (int i = 0; i < V; i++) { + visited[i] = false; + dist[i] = INT_MAX; + + } + + visited[v] = true; + dist[v] = 0; + queue.push_back(v); + + while (!queue.empty()) { + v = queue.front(); + cout << v << " "; + queue.pop_front(); + for (auto adjacent : adj[v]) { + if (!visited[adjacent]) { + visited[adjacent] = true; + dist[v] = dist[v] + 1; + queue.push_back(adjacent); + if (adjacent == w) { + return true; + } + } + } + } + return false; +} + +void Graph::printShortPath(int v, int w) { + +} int main(){ Graph network(4); @@ -65,15 +105,21 @@ int main(){ network.addEdge(2, 3); //C dislikes D network.addEdge(2, 1); //C dislikes B network.printGraph(); - queue<int> queue; + const int i = network.getNumNodes(); list<int> nodes[4]; cout << "\n" << "Number of nodes: " << i << "\n"; - vector<bool> visited[4]; - + cout << "Breadth First Traversal from A: \n"; + //network.BFS(0, 3); //Traversal from source to destination (0 = A, 1 = B, 2 = C, 3 = D) +} + +vector<int> findFriends(Graph network) { + vector<int> friends; + + return friends; } -bool isAdversary(Graph network, vector<bool> visited[4]) { +bool isFriend(Graph network) { return true; } \ No newline at end of file diff --git a/Problem3/Problem3.cpp b/Problem3/Problem3.cpp @@ -1,4 +1,4 @@ -// Problem 1: Huffman Coding +// Problem 3: Huffman Coding // Description: Implement a Huffman coding algorithm. // Course: IT405G - Datastructures and Algorithms // Authors: William Lindholm, Lili Tran, Victor Adamson @@ -9,6 +9,7 @@ #include <iostream> #include <vector> #include <queue> +#include <map> using namespace std; @@ -65,9 +66,32 @@ public: * 1 1 : b * @param bitString: the bitstring of the node */ - void printTree(vector<char>& bitString) const + void printTree(const string& bitString = "") const { + if (!left && !right) { + cout << bitString << ": " << c << endl; + return; + } + if (left) left->printTree(bitString + "0"); + if (right) right->printTree(bitString + "1"); + } + + /* + * Construct a map of the characters and their codes + * Since codes is passed as a reference, it will be modified + * @param codes: the map to construct + * @param bitString: the bitstring of the node + */ + void constructMap(map<char, string>& codes, const string& bitString = "") + { + if (!left && !right) { + codes[c] = bitString; + return; + } + + if (left) left->constructMap(codes, bitString + "0"); + if (right) right->constructMap(codes, bitString + "1"); } private: @@ -97,87 +121,140 @@ struct TreeWrapper Tree* tree; }; -/* -* Function: calculateWeight -* Calculate the weight of a string -* @param plainText: the string to calculate the weight of -* @param targetLetter: the letter to calculate the weight of -*/ -int calculateWeight(string plainText, char targetLetter) + +class HuffmanEncoder { - int weight = 0; - for (int i = 0; i < (int)plainText.size(); i++) +public: + /* + * Constructor + * @param plainText: the string to encode + */ + HuffmanEncoder(string plainText) + { + this->plainText = plainText; + } + + /* + * Encode the string + * @return: the encoded string + */ + void printCodes() + { + auto subTrees = createLeaves(); + this->huffmanTree = buildTree(subTrees); + Tree* root = this->getRoot(); + root->printTree(); + } + + + /* + * Get the codes of the characters + * @return: a map of the characters and their codes + */ + map<char, string> getCodes() + { + auto subTrees = createLeaves(); + this->huffmanTree = buildTree(subTrees); + Tree* root = this->getRoot(); + map<char, string> codes; + root->constructMap(codes); + return codes; + } + + /* + * Encode the string + * @return: the encoded string + */ + string encode() { - if (plainText[i] == targetLetter) + auto codes = getCodes(); + string encodedString = ""; + for (char c : plainText) { - weight++; + encodedString += codes[c]; + encodedString += " "; } + return encodedString; } - return weight; -} -class HuffmanTree -{ - public: - /* - * Constructor - * @param plainText: the string to encode - */ - HuffmanTree(string plainText) + /* + * Get the root of the tree + * @return: the root of the + */ + Tree* getRoot() + { + return huffmanTree.top().tree; + } + +private: + string plainText; + priority_queue<TreeWrapper> huffmanTree; + + /* + * Create the leaves of the tree, and push them to a priority queue + * Note: the priority queue is sorted by the weight of the nodes + * But the tree is not built yet + * @return: a priority queue of the leaves + */ + priority_queue<TreeWrapper> createLeaves() + { + priority_queue<TreeWrapper> q; + + map<char, int> charWeights; + + // calculate frequencies + for (char c : plainText) { - this->plainText = plainText; + charWeights[c]++; } - /* - * Encode the string - * @return: the encoded string - */ - string encode() + // Create leaves and push them to the queue + for (auto& pair : charWeights) { - auto subTrees = buildSubTrees(); - auto root = buildTree(subTrees); - - return ""; + q.push(TreeWrapper(new Tree(pair.second, pair.first))); } - private: - string plainText; + return q; + } - priority_queue<TreeWrapper> buildSubTrees() + /* + * Build the tree from the priority queue + * @param q: the priority queue of the leaves + * @return: the root of the tree + */ + priority_queue<TreeWrapper> buildTree(priority_queue<TreeWrapper> q) + { + if (q.size() == 1) { - priority_queue<TreeWrapper> q; - - for (int i = 0; i < (int)plainText.size(); i++) - { - int weight = calculateWeight(plainText, plainText[i]); - q.push(TreeWrapper(new Tree(weight, plainText[i]))); - } - return q; } - priority_queue<TreeWrapper> buildTree(priority_queue<TreeWrapper> q) - { - if (q.size() == 1) - { - return q; - } - - TreeWrapper t1 = q.top(); - q.pop(); - TreeWrapper t2 = q.top(); - q.pop(); - q.push(TreeWrapper(new Tree(t1.tree->getWeight() + t2.tree->getWeight(), t1.tree, t2.tree))); - - return buildTree(q); - } + TreeWrapper t1 = q.top(); + q.pop(); + TreeWrapper t2 = q.top(); + q.pop(); + q.push(TreeWrapper(new Tree(t1.tree->getWeight() + t2.tree->getWeight(), t1.tree, t2.tree))); + + return buildTree(q); + } }; int main() { - HuffmanTree huffmanTree("abacabad"); - string encoded = huffmanTree.encode(); + string unEncodedString = "AAAABBBCCCCCCCCCCCCCCCCCCCCCCCCCCCD"; + HuffmanEncoder huffmanTree(unEncodedString); + huffmanTree.printCodes(); + + string encodedString = huffmanTree.encode(); + printf("Encoded string: %s\n", encodedString.c_str()); + + int unEncodedLen = (int)(unEncodedString.length()*8); + int encodedLen = (int)encodedString.length(); - cout << "The string was encoded to: " << encoded << endl; + printf("Unencoded length: %d\n", unEncodedLen); + printf("Encoded length: %d\n", encodedLen); + printf("saved %d bits\n", unEncodedLen - encodedLen); + + return 0; };