Skip to content

Commit c88bd81

Browse files
committed
Soham Haldar| Huffman encoder( huffman.cpp, compressor.py, decompressor.py)| Added 1 folder with 3 files
1 parent a8fb78b commit c88bd81

File tree

3 files changed

+170
-0
lines changed

3 files changed

+170
-0
lines changed

Huffman compressor/compressor.py

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import math
2+
def compress(ifile, codes, ofile):
3+
symbol_codes = {}
4+
with open(codes, 'r') as f:
5+
for line in f:
6+
last_space_index = line.rfind(' ')
7+
if last_space_index != -1:
8+
symbol = line[:last_space_index]
9+
code = line[last_space_index + 1:].strip()
10+
symbol_codes[symbol] = code
11+
12+
with open(ifile, 'r') as f:
13+
itext = f.read().strip()
14+
compressed = ''
15+
for c in itext:
16+
if c.isalpha() or c.isspace():
17+
c=c.upper()
18+
if c in symbol_codes:
19+
compressed += symbol_codes[c]
20+
with open(ofile, 'w') as f:
21+
f.write(compressed)
22+
entropy(itext,compressed)
23+
def entropy(a,b):
24+
D = {}
25+
E = {}
26+
for i in a:
27+
if i not in D:
28+
D[i]=1
29+
else:
30+
D[i]+=1
31+
for i in b:
32+
if i not in E:
33+
E[i]=1
34+
else:
35+
E[i]+=1
36+
entropya=0
37+
for i in D:
38+
entropya+=(D[i]/len(a))*math.log2((len(a)/D[i]))
39+
entropyb=0
40+
for i in E:
41+
entropyb+=(E[i]/len(b))*math.log2((len(b)/E[i]))
42+
print("The information gain from compression is: ",entropya-entropyb)
43+
44+
ifile = input("Enter your input filename: ")
45+
codes = input("Enter the filename where you want to save your codes: ")
46+
ofile = input("Enter the filename where you want your compressed document saved: ")
47+
compress(ifile, codes, ofile)
48+
print("Compressed code has been written to:", ofile)

Huffman compressor/decompressor.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
def decompress(ifile, codes,ofile):
2+
symbol_codes = {}
3+
with open(codes, 'r') as f:
4+
for line in f:
5+
last_space_index = line.rfind(' ')
6+
if last_space_index != -1:
7+
symbol = line[:last_space_index]
8+
code = line[last_space_index + 1:].strip()
9+
symbol_codes[code] = symbol
10+
with open(ifile, 'r') as f:
11+
compressed = f.readline()
12+
decompressed = ''
13+
current = ''
14+
for bit in compressed:
15+
current += bit
16+
if current in symbol_codes.keys():
17+
decompressed += symbol_codes[current]
18+
current = ''
19+
with open(ofile, 'w') as f:
20+
f.write(decompressed)
21+
22+
ifile = input("Enter your input (compressed) filename: ")
23+
codes = input("Enter the filename where you have saved your codes: ")
24+
ofile = input("Enter the filename where you want your decompressed document saved: ")
25+
decompress(ifile, codes,ofile)
26+
print("Decompressed code has been written to:", ofile)
27+

Huffman compressor/huffman.cpp

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#include <iostream>
2+
#include <fstream>
3+
#include <unordered_map>
4+
#include <string>
5+
#include <queue>
6+
using namespace std;
7+
struct Node{
8+
char symbol;
9+
unsigned freq;
10+
Node *left;
11+
Node *right;
12+
13+
Node(char symbol, unsigned freq) : symbol(symbol), freq(freq), left(nullptr), right(nullptr) {}
14+
};
15+
16+
struct comp{
17+
bool operator()(Node *l, Node *r){
18+
return l->freq > r->freq;
19+
}
20+
};
21+
22+
void printCodes(Node *root, string str, unordered_map<char, string> &huffmanCodes){
23+
if (!root){
24+
return;
25+
}
26+
printCodes(root->left, str + "0", huffmanCodes);
27+
printCodes(root->right, str + "1", huffmanCodes);
28+
if (!root->left && !root->right){
29+
huffmanCodes[root->symbol] = str;
30+
}
31+
}
32+
unordered_map<char, string> generateHuffmanCodes(istream &input) {
33+
unordered_map<char, unsigned> freq;
34+
string line;
35+
while (getline(input, line)) {
36+
for (char c : line) {
37+
if (isalpha(c) || isspace(c)) {
38+
freq[toupper(c)]++;
39+
}
40+
}
41+
}
42+
43+
priority_queue<Node *, vector<Node *>, comp> pq;
44+
for (const auto &pair : freq) {
45+
pq.push(new Node(pair.first, pair.second));
46+
}
47+
while (pq.size() > 1) {
48+
Node *left = pq.top();
49+
pq.pop();
50+
Node *right = pq.top();
51+
pq.pop();
52+
53+
Node *mergedNode = new Node('$', left->freq + right->freq);
54+
mergedNode->left = left;
55+
mergedNode->right = right;
56+
57+
pq.push(mergedNode);
58+
}
59+
Node *root = pq.top();
60+
unordered_map<char, string> huffmanCodes;
61+
queue<pair<Node *, string>> q;
62+
q.push({root, ""});
63+
while (!q.empty()) {
64+
Node *current = q.front().first;
65+
string currentCode = q.front().second;
66+
q.pop();
67+
if (current->left) {
68+
q.push({current->left, currentCode + "0"});
69+
}
70+
if (current->right) {
71+
q.push({current->right, currentCode + "1"});
72+
}
73+
if (!current->left && !current->right) {
74+
huffmanCodes[current->symbol] = currentCode;
75+
}
76+
}
77+
delete root;
78+
return huffmanCodes;
79+
}
80+
int main(){
81+
string file;
82+
cout<<"Enter file name: ";//Your input text file goes here
83+
getline(cin, file);
84+
ifstream input (file);
85+
string ofile;
86+
cout<<"Enter your output file name, where your codes will be saved: ";//Your output text file goes here
87+
getline(cin, ofile);
88+
ofstream outputFile(ofile);
89+
unordered_map<char, string> huffmanCodes = generateHuffmanCodes(input);
90+
for (const auto &pair : huffmanCodes) {
91+
cout << pair.first << " " << pair.second << "\n";
92+
outputFile << pair.first << " " << pair.second << "\n";
93+
}
94+
return 0;
95+
}

0 commit comments

Comments
 (0)