Skip to content

Instantly share code, notes, and snippets.

@harshildarji
Last active April 15, 2016 13:01
Show Gist options
  • Save harshildarji/72591e253403cea56783b1e28d09d79a to your computer and use it in GitHub Desktop.
Save harshildarji/72591e253403cea56783b1e28d09d79a to your computer and use it in GitHub Desktop.
This code is to implement Shannon Fano compression algorithm. This takes a string from the user and gives appropriate code for each symbol in the string.
using System;
using System.Linq;
namespace DC4
{
class Program
{
class fano
{
public float pro;
public int[] arr = new int[20];
public int top;
}
static void Main(string[] args)
{
fano[] f = Enumerable.Range(0, 20).Select(ind => new fano()).ToArray();
Console.Write("Enter String: ");
string str = Console.ReadLine().ToLower().Replace(" ", "#");
Console.WriteLine("Space will be represented by #");
int n = str.Length, count = 1, flag = 0, pos = 0;
int[] d = new int[n];
int[] d1 = new int[n];
char[] c1 = new char[n];
var c = str.ToCharArray();
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
if (c[i] == c[j])
{
count++;
}
}
d[i] = count;
count = 1;
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (c[i] == c1[j])
{
flag++;
}
}
if (flag == 0)
{
c1[pos] = c[i];
d1[pos] = d[i];
pos++;
}
flag = 0;
}
for (int i = 0; i < pos; i++)
{
Console.Write("{0}\t", c1[i]);
}
Console.WriteLine();
for (int i = 0; i < pos; i++)
{
Console.Write("{0}\t", d1[i]);
}
int temp;
char ch;
for (int i = 0; i < pos; i++)
{
for (int j = i + 1; j < pos; j++)
{
if (d1[i] > d1[j])
{
temp = d1[i];
ch = c1[i];
d1[i] = d1[j];
c1[i] = c1[j];
d1[j] = temp;
c1[j] = ch;
}
}
}
Console.WriteLine("\n\nAfter Sorting: ");
for (int i = pos - 1; i >= 0; i--)
{
Console.Write("{0}\t", c1[i]);
}
Console.WriteLine();
for (int i = pos - 1; i >= 0; i--)
{
Console.Write("{0}\t", d1[i]);
}
double infoBit = 0;
for (int i = 0; i < pos; i++)
{
double prob, si;
prob = d1[i] / (double)n;
f[i].pro = (float)prob;
si = -(Math.Log(prob) / Math.Log(2));
infoBit += (si * d1[i]);
}
Console.WriteLine("\nTotal Information Count: {0}", infoBit + " Bits");
Console.WriteLine("Number of Bits required before Compression: {0}", (n * 8));
for (int i = 0; i < pos; i++)
f[i].top = -1;
shannon(0, pos - 1, f);
int sfBits = 0;
string[] code = new string[pos];
Console.WriteLine("\nShannon-Fano Code:");
for (int i = pos - 1; i >= 0; i--)
{
string codec = " ";
int sfSize = 0;
Console.Write("{0}: {1}\t", c1[i], d1[i]);
for (int j = 0; j <= f[i].top; j++)
{
Console.Write("{0}", f[i].arr[j]);
codec += f[i].arr[j];
sfSize++;
}
code[i] = codec;
sfBits += (sfSize * d1[i]);
Console.Write("\n");
}
Console.WriteLine("Number of Shannon-Fano Bits: {0}", sfBits);
string cStr = " ";
foreach (var item in str)
{
var index = Array.IndexOf(c1, item);
cStr += code.ElementAt(index);
}
Console.WriteLine("\nCoded String: ");
Console.WriteLine(cStr.Replace(" ",""));
Console.ReadKey();
}
static void shannon(int l, int h, fano[] f)
{
float set1 = 0, set2 = 0, diff1 = 0, diff2 = 0;
int i, d, j, k = 0;
if ((l + 1) == h || l == h || l > h)
{
if (l == h || l > h)
return;
f[h].arr[++(f[h].top)] = 0;
f[l].arr[++(f[l].top)] = 1;
return;
}
else
{
for (i = l; i <= h - 1; i++)
set1 = set1 + f[i].pro;
set2 = set2 + f[h].pro;
diff1 = set1 - set2;
if (diff1 < 0)
diff1 = diff1 * -1;
j = 2;
while (j != h - l + 1)
{
k = h - j;
set1 = set2 = 0;
for (i = l; i <= k; i++)
set1 = set1 + f[i].pro;
for (i = h; i > k; i--)
set2 = set2 + f[i].pro;
diff2 = set1 - set2;
if (diff2 < 0)
diff2 = diff2 * -1;
if (diff2 >= diff1)
break;
diff1 = diff2;
j++;
}
k++;
for (i = l; i <= k; i++)
f[i].arr[++(f[i].top)] = 1;
for (i = k + 1; i <= h; i++)
f[i].arr[++(f[i].top)] = 0;
shannon(l, k, f);
shannon(k + 1, h, f);
}
}
}
}
@harshildarji
Copy link
Author

Output Example:
capture

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment