Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Assignment No-2

Download as pdf or txt
Download as pdf or txt
You are on page 1of 8

1.

Write a program in C/C++/ Java to implement huffman Code using greedy methods
and also calculate the best case and worst case complexity.

#include <iostream>
#include <vector>
#include <queue>
#include <unordered_map>
#include <string>
#include <functional>
#include <memory>
using namespace std;
// Structure representing a node in the Huffman tree
struct HuffmanNode {
char character;
int frequency;
shared_ptr<HuffmanNode> left;
shared_ptr<HuffmanNode> right;
HuffmanNode(char character, int frequency)
: character(character), frequency(frequency), left(nullptr), right(nullptr) {}
};
// Comparator for priority queue (min-heap)
struct HuffmanComparator {
bool operator()(const shared_ptr<HuffmanNode>& a, const shared_ptr<HuffmanNode>& b) {
return a->frequency > b->frequency; // Min-heap, lower frequency nodes have higher priority }
};
// Function to build the Huffman Tree
shared_ptr<HuffmanNode> buildHuffmanTree(const unordered_map<char, int>& frequencyMap) {
priority_queue<shared_ptr<HuffmanNode>, vector<shared_ptr<HuffmanNode>>,
HuffmanComparator> minHeap;
// Insert all characters and their frequencies into the min-heap
for (const auto& entry : frequencyMap) {
minHeap.push(make_shared<HuffmanNode>(entry.first, entry.second)); }
// Build the Huffman Tree
while (minHeap.size() > 1) {
// Extract the two nodes with the lowest frequency
shared_ptr<HuffmanNode> left = minHeap.top();
minHeap.pop();
shared_ptr<HuffmanNode> right = minHeap.top();
minHeap.pop();
// Create a new internal node with these two nodes as children
int combinedFrequency = left->frequency + right->frequency;
shared_ptr<HuffmanNode> internalNode = make_shared<HuffmanNode>('\0',
combinedFrequency);
internalNode->left = left;
internalNode->right = right;
minHeap.push(internalNode); // Add the new internal node back into the heap
}
return minHeap.top(); // Root of the Huffman Tree
}
// Function to generate Huffman codes from the Huffman Tree
void generateHuffmanCodes(
shared_ptr<HuffmanNode> root,
const string& currentCode,
unordered_map<char, string>& huffmanCodes
){
if (!root) {
return; // Empty node
}
if (!root->left && !root->right) { // Leaf node
huffmanCodes[root->character] = currentCode;
return;
}
// Recur to the left and right children with updated codes
generateHuffmanCodes(root->left, currentCode + "0", huffmanCodes);
generateHuffmanCodes(root->right, currentCode + "1", huffmanCodes);
}
// Main function demonstrating Huffman Coding
int main() {
// Sample data and frequencies
unordered_map<char, int> frequencyMap = {
{'A', 5},
{'B', 9},
{'C', 12},
{'D', 13},
{'E', 16},
{'F', 45}
};
// Build the Huffman Tree
shared_ptr<HuffmanNode> root = buildHuffmanTree(frequencyMap);
// Generate Huffman Codes
unordered_map<char, string> huffmanCodes;
generateHuffmanCodes(root, "", huffmanCodes);
// Display the Huffman Codes
cout << "Huffman Codes:\n";
for (const auto& entry : huffmanCodes) {
cout << entry.first << ": " << entry.second << endl; }
return 0;
}
2. Write a program in C/C++/ Java to find Minimum number of multiplications in
Matrix Chain Multiplication.

#include <iostream>
#include <vector>
#include <limits>

// Function to find the minimum number of multiplications and optimal parenthesization


void matrixChainOrder(
const std::vector<int>& dimensions,
std::vector<std::vector<int>>& m,
std::vector<std::vector<int>>& s
){
int n = dimensions.size() - 1;

// Initialize the cost matrix with 0 for diagonal elements


for (int i = 1; i <= n; ++i) {
m[i][i] = 0;
}

// Iterate over the chain lengths


for (int length = 2; length <= n; ++length) {
for (int i = 1; i <= n - length + 1; ++i) {
int j = i + length - 1;
m[i][j] = std::numeric_limits<int>::max();
// Find the minimum cost for this subchain
for (int k = i; k < j; ++k) {
int cost = m[i][k] + m[k + 1][j] + dimensions[i - 1] * dimensions[k] * dimensions[j];
if (cost < m[i][j]) {
m[i][j] = cost;
s[i][j] = k; // Store the optimal split point
}
}
}
}
}

// Function to print the optimal parenthesization


void printOptimalParens(const std::vector<std::vector<int>>& s, int i, int j) {
if (i == j) {
std::cout << "A" << i;
} else {
std::cout << "(";
printOptimalParens(s, i, s[i][j]);
printOptimalParens(s, s[i][j] + 1, j);
std::cout << ")";
}
}

// Main function to demonstrate Matrix Chain Multiplication


int main() {
// Example dimensions of the matrices
std::vector<int> dimensions = {30, 35, 15, 5, 10, 20, 25}; // A1 (30x35), A2 (35x15), A3 (15x5), etc.

int n = dimensions.size() - 1;

// Cost matrix and split matrix


std::vector<std::vector<int>> m(n + 1, std::vector<int>(n + 1, 0));
std::vector<std::vector<int>> s(n + 1, std::vector<int>(n + 1, 0));

// Calculate the minimum cost and parenthesization


matrixChainOrder(dimensions, m, s);

std::cout << "Minimum number of scalar multiplications is: " << m[1][n] << std::endl;

std::cout << "Optimal parenthesization: ";


printOptimalParens(s, 1, n);
std::cout << std::endl;

return 0;
}

3. Write a Program in C/C++/Java to find only length of Longest Common


Subsequence.

#include <iostream>
#include <vector>
#include <string>

int longestCommonSubsequence(const std::string& str1, const std::string& str2) {


int m = str1.length();
int n = str2.length();

// Create a 2D vector to store the length of LCS


std::vector<std::vector<int>> lcs(m + 1, std::vector<int>(n + 1, 0));

// Build the LCS matrix


for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
if (str1[i - 1] == str2[j - 1]) {
lcs[i][j] = lcs[i - 1][j - 1] + 1; // If characters match, increase the length
} else {
lcs[i][j] = std::max(lcs[i - 1][j], lcs[i][j - 1]); // Take the maximum of excluding one character
}
}
}

// The last element in the matrix contains the length of the LCS
return lcs[m][n];
}

int main() {
std::string str1 = "AGGTAB";
std::string str2 = "GXTXAYB";

int lcsLength = longestCommonSubsequence(str1, str2);

std::cout << "Length of Longest Common Subsequence: " << lcsLength << std::endl;

return 0;
}

4. Write programs in C/C++/ Java to implement DFS and BFS. Compare the time
complexity.

#include <iostream>
#include <vector>
#include <stack>

// Graph structure using an adjacency list


class Graph {
public:
Graph(int vertices) : vertices(vertices), adjList(vertices) {}

void addEdge(int src, int dest) {


adjList[src].push_back(dest);
}

void dfs(int startVertex) {


std::vector<bool> visited(vertices, false);
dfsRecursive(startVertex, visited);
}

private:
int vertices;
std::vector<std::vector<int>> adjList;

void dfsRecursive(int vertex, std::vector<bool>& visited) {


// Mark the current vertex as visited
visited[vertex] = true;
std::cout << vertex << " ";

// Recur for all adjacent vertices


for (int neighbor : adjList[vertex]) {
if (!visited[neighbor]) {
dfsRecursive(neighbor, visited);
}
}
}
};

int main() {
Graph g(6);

// Add edges to create a simple graph


g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 3);
g.addEdge(2, 3);
g.addEdge(3, 4);
g.addEdge(4, 5);

std::cout << "DFS traversal starting from vertex 0: ";


g.dfs(0);

return 0;
}

5. Write a program in C/C++/ Java to determine if a given graph is a Hamiltonian cycle


or not.

#include <iostream>
#include <vector>
#include <algorithm>
// Check if the given path is a Hamiltonian cycle
bool isHamiltonianCycle(const std::vector<std::vector<int>>& graph, const std::vector<int>& path) {
int n = graph.size();
// Check if the path starts and ends at the same vertex
if (path[0] != path[n - 1]) {
return false;
}

// Check if the path contains all vertices without repetition


std::vector<bool> visited(n, false);
for (int i = 0; i < n - 1; ++i) {
int u = path[i];
int v = path[i + 1];
if (visited[u] || graph[u][v] == 0) {
return false; // If vertex is visited or there's no edge
}
visited[u] = true;
}
return true;
}

// Backtracking function to find Hamiltonian cycle


bool findHamiltonianCycle(
const std::vector<std::vector<int>>& graph,
std::vector<int>& path,
int pos
){
int n = graph.size();

// If all vertices are included in the path, check if it's a Hamiltonian cycle
if (pos == n) {
return isHamiltonianCycle(graph, path);
}

// Try different vertices to add to the path


for (int v = 1; v < n; ++v) {
if (std::find(path.begin(), path.begin() + pos, v) == path.begin() + pos && graph[path[pos - 1]][v] !=
0) {
// Add vertex to the path
path[pos] = v;

// Recur to build the rest of the path


if (findHamiltonianCycle(graph, path, pos + 1)) {
return true;
}

// If no solution is found, backtrack


path[pos] = -1;
}
}

return false;
}

bool hasHamiltonianCycle(const std::vector<std::vector<int>>& graph) {


int n = graph.size();

// Create a path with n vertices, initialized with -1


std::vector<int> path(n, -1);

// Start the path from vertex 0


path[0] = 0;

return findHamiltonianCycle(graph, path, 1);


}

int main() {
// Example adjacency matrix for a graph
std::vector<std::vector<int>> graph = {
{0, 1, 0, 1, 0},
{1, 0, 1, 0, 1},
{0, 1, 0, 1, 1},
{1, 0, 1, 0, 1},
{0, 1, 1, 1, 0}
};

if (hasHamiltonianCycle(graph)) {
std::cout << "The graph has a Hamiltonian cycle." << std::endl;
} else {
std::cout << "The graph does not have a Hamiltonian cycle." << std::endl;
}

return 0;
}

You might also like