Пример #1
0
        private static bool TestBuildHuffmanCode(Dictionary<char, double> charFrequency, Dictionary<char, string> huffmanCodeCorrect)
        {
            bool testPassed = true;

            HuffmanTree test = new HuffmanTree(charFrequency);

            var huffmanCodeGenerated = test.dict;

            string pool = "";
            foreach (KeyValuePair<char, string> kvp in huffmanCodeCorrect)
            {
                pool += kvp.Key;
            }

            foreach (char s in pool)
            {
                Console.WriteLine(s + "\t" + huffmanCodeGenerated[s] + "\t==\t" + s + "\t" + huffmanCodeCorrect[s]);
                if (huffmanCodeGenerated[s] != huffmanCodeCorrect[s])
                    testPassed = false;
            }

            if (testPassed)
                Console.WriteLine("Test: Passed.\n");
            else
                Console.WriteLine("Test: Failed.");

            return testPassed;
        }
Пример #2
0
        static void Main(string[] args)
        {
            if (args.Length < 1 || args[0] == string.Empty)
            {
                Console.WriteLine("Please specify an input parameter.");
                return;
            }

            var orig = args[0];

            var hf = new HuffmanTree()
                     .Build(orig);

            var encoded = hf.Encode(orig);
            var decoded = hf.Decode(encoded);

            Console.WriteLine($"Original message: {orig}");
            Console.WriteLine($"Encoded message: {encoded.ToBinaryString()}");
            Console.WriteLine($"Decoded message: {decoded}");

            hf.Root.Print();
        }
Пример #3
0
        static void importfromfileTest(string[] args)
        {
            Dictionary<char, int> zeichentabelle;
            Dictionary<char, double> relativeAnzahl;

            string file = args[0];
            string text = "";
            try
            {
                text = Dictcreator.getInput(file);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            zeichentabelle = Dictcreator.createDictionaryFromString(text);
            relativeAnzahl = Dictcreator.getRelativeFrequencyDict(zeichentabelle);
            HuffmanTree tree = new HuffmanTree(relativeAnzahl);

            tree.printTree(tree.root);
        }
Пример #4
0
        // this method creates a tree based on text
        public static HuffmanTree CreateFromText(string text)
        {
            // the list that we wanna fill up with nodes
            List <HuffmanNode> nodeList = new List <HuffmanNode>();

            // all the characters from the text
            char[] characters = text.ToCharArray();
            // loop thought the characters
            for (int i = 0; i < characters.Length; i++)
            {
                // the character as a string
                string read = characters[i].ToString();
                // has the node already been created?
                if (nodeList.Exists(x => x.Symbol == read))
                {
                    // If is yes, find the index of the Node and increase the frequency of the Node.
                    nodeList[nodeList.FindIndex(y => y.Symbol == read)].Frequency++;
                }
                else
                {
                    // If is no, create a new node and add to the List of Nodes
                    nodeList.Add(new HuffmanNode(read));
                }
            }
            // sort them, this is done based on frequency because of IComparable<HuffmanNode>.CompareTo
            nodeList.Sort();
            // loop thought them, until only one is left
            while (nodeList.Count > 1)
            {
                // Get the node of the first index of List, this is the one with the lowest frequency
                HuffmanNode node1 = nodeList[0];
                // and delete it.
                nodeList.RemoveAt(0);
                // do the same thing again
                HuffmanNode node2 = nodeList[0];
                nodeList.RemoveAt(0);
                // make a parant node with node1 and node2 and the left and right child nodes
                nodeList.Add(new HuffmanNode(node1, node2));
                // and sort it again according to frequency.
                nodeList.Sort();
            }
            // create a tree based on the remaining root node
            HuffmanTree tree = new HuffmanTree(nodeList[0]);

            // this is a recursive function to set the binary code of every leaf node
            void setCodeToTheTree(HuffmanNode Nodes, BitArray code = null)
            {
                // if the current code is not set, set it to an empty BitArray
                if (code == null)
                {
                    code = new BitArray(new bool[] { });
                }
                // if the code is empty do nothing
                if (Nodes == null)
                {
                    return;
                }
                // if there is no left node and right node, then set the code based on the current code
                if (Nodes.LeftChildNode == null && Nodes.RightChildNode == null)
                {
                    Nodes.Code = code;
                    return;
                }
                // create a bitlist for the left node
                BitList left = BitList.Parse(code);

                // add false for the left side
                left.Add(false);
                // call this function recursively, with the left bitlist and the left side node
                setCodeToTheTree(Nodes.LeftChildNode, left.ToBitArray());
                // create a bitlist for the right node
                BitList right = BitList.Parse(code);

                // add true for the right side
                right.Add(true);
                // call the function recursively, with the right bitlist and the right side node
                setCodeToTheTree(Nodes.RightChildNode, right.ToBitArray());
            }

            // call the recursive function
            setCodeToTheTree(tree.Root);
            // the tree
            return(tree);
        }
Пример #5
0
        static void Main(string[] args)
        {
            HuffmanTree.EncodingType = Encoding.UTF8;
            List <Article> articles = new List <Article> {
                new Article()
                {
                    title   = "den danske grundlov",
                    extract = SomeRandomText.DenDanskeGrundlov
                },
                new Article()
                {
                    title   = "mini srp infohæfte 2018",
                    extract = File.ReadAllText(@"E:\Libraries\Documents\Visual Studio 2017\Projects\huffman\huffman\MiniSRPinfohæfte2018.txt")
                },
                new Article()
                {
                    title   = "euklids elementer",
                    extract = File.ReadAllText(@"E:\Libraries\Documents\Visual Studio 2017\Projects\huffman\huffman\EuklidsElementer.txt")
                }
            };

            if (Directory.Exists(OUTPUT_DIR))
            {
                Directory.Delete(OUTPUT_DIR, true);
            }
            var outputDir = Directory.CreateDirectory(OUTPUT_DIR);

            foreach (var article in articles)
            {
                var tree         = HuffmanTree.CreateFromText(article.extract);
                var subDir       = outputDir.CreateSubdirectory(article.title);
                var treeFilePath = Path.Combine(subDir.FullName, "tree.json");
                File.Create(treeFilePath).Close();
                File.WriteAllText(treeFilePath, tree.JSONEncode());

                var originalFilePath = Path.Combine(subDir.FullName, "original.txt");
                File.Create(originalFilePath).Close();
                File.WriteAllText(originalFilePath, article.extract);

                var encodedFilePath = Path.Combine(subDir.FullName, "encoded.txt");
                File.Create(encodedFilePath).Close();
                var encodedData = tree.Encode(article.extract);
                File.WriteAllBytes(encodedFilePath, encodedData);

                var encodedReadAbleFilePath = Path.Combine(subDir.FullName, "encoded_readable.txt");
                File.Create(encodedReadAbleFilePath).Close();
                File.WriteAllText(encodedReadAbleFilePath, (new BitArray(encodedData)).Print());

                var decodedFilePath = Path.Combine(subDir.FullName, "decoded.txt");
                File.Create(decodedFilePath).Close();
                var decodedData = tree.Decode(encodedData);
                File.WriteAllText(decodedFilePath, decodedData);

                var statsFilePath = Path.Combine(subDir.FullName, "stats.txt");
                File.Create(statsFilePath).Close();
                File.WriteAllLines(statsFilePath, new string[] {
                    "original size: " + (article.extract.Length * 8) + " b",
                    "compressed size: " + encodedData.Length + " b",
                    "compression percentage: " + (100 * ((double)encodedData.Length / ((double)HuffmanTree.EncodingType.GetBytes(article.extract).Length))) + "%",
                    "tree size as json: " + (HuffmanTree.EncodingType.GetBytes(tree.JSONEncode()).Length) + " b",
                    "tree size as bytes: " + (new Func <string>(() => {
                        byte[] bytes;
                        IFormatter formatter = new BinaryFormatter();
                        using (MemoryStream stream = new MemoryStream()){
                            formatter.Serialize(stream, tree);
                            bytes = stream.ToArray();
                        }
                        return("" + bytes.Length);
                    }))() + " b",
                    "lossness: " + (article.extract == decodedData ? "yes" : (new Func <string>(() => {
                        string re = "no" + Environment.NewLine;
                        if (article.extract.Length == decodedData.Length)
                        {
                            List <string> errors = new List <string>();
                            for (int i = 0; i < article.extract.Length; i++)
                            {
                                if (article.extract[i] != decodedData[i])
                                {
                                    errors.Add("position " + i + " does not match; original: " + article.extract[i].ToString() + ", decoded: " + decodedData[i].ToString());
                                }
                            }
                            re += String.Join(Environment.NewLine, errors.ToArray());
                        }
                        else
                        {
                            re += "not the same length; original: " + article.extract.Length + ", decoded: " + decodedData.Length;
                        }
                        return(re);
                    }))())
                });
            }
            Console.WriteLine("Done");
            Thread.Sleep(-1);
        }
Пример #6
0
        // this method creates a tree based on text
        // Denne funktion laver et træ baseret på tekst
        public static HuffmanTree CreateFromText(string text)
        {
            // the list that we wanna fill up with nodes
            // Listen der skal fyldes med noder
            List <HuffmanNode> nodeList = new List <HuffmanNode>();

            // all the characters from the text
            // Alle symbolerne fra teksten
            char[] characters = text.ToCharArray();
            // loop thought the characters
            // Gentag igennem symbolerne
            for (int i = 0; i < characters.Length; i++)
            {
                // the character as a string
                // Symbolerne som strenge
                string read = characters[i].ToString();
                // has the node already been created?
                // Er noden allerede blevet skabt?
                if (nodeList.Exists(x => x.Symbol == read))
                {
                    // If is yes, find the index of the Node and increase the frequency of the Node.
                    // Hvis ja, find indekset for noden og øg frekvensen for node
                    nodeList[nodeList.FindIndex(y => y.Symbol == read)].Frequency++;
                }
                else
                {
                    // If is no, create a new node and add to the List of Nodes
                    // Hvis nej, skab en ny node og tilføj den til listen over node
                    nodeList.Add(new HuffmanNode(read));
                }
            }
            // sort them, this is done based on frequency because of IComparable<HuffmanNode>.CompareTo
            // Sorter dem, dette gøres baseret på frekvens fordi at IComparable<HuffmanNode>.CompareTo
            nodeList.Sort();
            // loop thought them, until only one is left
            // Kør igennem dem alle sammen indtil der kun er en tilbage
            while (nodeList.Count > 1)
            {
                // Get the node of the first index of List, this is the one with the lowest frequency
                // Få noden for det første indeks af Listen, dette er den med den laveste frekvens
                HuffmanNode node1 = nodeList[0];
                // and delete it.
                // Fjern den
                nodeList.RemoveAt(0);
                // do the same thing again
                // Gør det samme igen
                HuffmanNode node2 = nodeList[0];
                nodeList.RemoveAt(0);
                // make a parant node with node1 and node2 and the left and right child nodes
                // Lav en parent-node med node1 og node1 og de venstre og højre child-noder
                nodeList.Add(new HuffmanNode(node1, node2));
                // and sort it again according to frequency.
                // Og sorter det igen efter frekvens
                nodeList.Sort();
            }
            // create a tree based on the remaining root node
            // Lav et træ baseret på den tilbageværende rod-node
            HuffmanTree tree = new HuffmanTree(nodeList[0]);

            // this is a recursive function to set the binary code of every leaf node
            // Dette er en rekursiv funktion for at sætte den binære værdi for hvert blad
            void setCodeToTheTree(HuffmanNode Nodes, BitArray code = null)
            {
                // if the current code is not set, set it to an empty BitArray
                // Hvis den nuværende kode ikke er sat, sættes den til et tomt BitArray
                if (code == null)
                {
                    code = new BitArray(new bool[] { });
                }
                // if the code is empty do nothing
                // Hvis koden er tom, gør intet
                if (Nodes == null)
                {
                    return;
                }
                // if there is no left node and right node, then set the code based on the current code
                // Hvis der ikke er nogen venstre node, sæt koden baseret på den nuværende kode
                if (Nodes.LeftChildNode == null && Nodes.RightChildNode == null)
                {
                    Nodes.Code = code;
                    return;
                }
                // create a bitlist for the left node
                // lav en bitliste for den venstre node
                BitList left = BitList.Parse(code);

                // add false for the left side
                // tilføj false for den venstre side
                left.Add(false);
                // call this function recursively, with the left bitlist and the left side node
                // Kald denne funktion rekursivt, med den venstre bitliste og den venstre node
                setCodeToTheTree(Nodes.LeftChildNode, left.ToBitArray());
                // create a bitlist for the right node
                // Lav en bitliste for den højre node
                BitList right = BitList.Parse(code);

                // add true for the right side
                // tilføj true for den højre side
                right.Add(true);
                // call the function recursively, with the right bitlist and the right side node
                // Kald denne funktion rekursivt, med den højre bitliste og den højre node
                setCodeToTheTree(Nodes.RightChildNode, right.ToBitArray());
            }

            // call the recursive function
            // Kald den rekursive funktion
            setCodeToTheTree(tree.Root);
            // the tree
            // Træet returneres
            return(tree);
        }