public OrderedLinkedList <TreeNode <CharacterFrequency> > TransferListToTree(OrderedLinkedList <TreeNode <CharacterFrequency> > orderedNodeList)
        {
            while (orderedNodeList.Count != 1)
            {
                TreeNode <CharacterFrequency> least = orderedNodeList.GetFirst();
                orderedNodeList.RemoveFirst();
                TreeNode <CharacterFrequency> nextLeast = orderedNodeList.GetFirst();
                orderedNodeList.RemoveFirst();

                TreeNode <CharacterFrequency> combinedLeast = new TreeNode <CharacterFrequency>(new CharacterFrequency('\0', (least.Element.Frequency + nextLeast.Element.Frequency)));
                combinedLeast.Left  = least;
                combinedLeast.Right = nextLeast;

                orderedNodeList.Add(combinedLeast);
            }
            return(orderedNodeList);
        }
Пример #2
0
        //Method used for compressing files
        static void Compress(string input, string output)
        {
            //start of method

            //Initilize variables
            int totalChars = 0; //Counts number of characters in file, used for decompression purposes
            BinaryTree <CharacterFrequency> charTree = new BinaryTree <CharacterFrequency>();
            StreamReader read = new StreamReader(input);

            //Create a dictionary of CharacterFrequency objects with the int key being the ascii code of each character
            IDictionary <int, CharacterFrequency> charDictionary = new Dictionary <int, CharacterFrequency>();

            //Read entire file character by character...
            while (!read.EndOfStream)
            {
                int i = read.Read();

                //checks if Dictionary contains the char i...
                if (!charDictionary.ContainsKey(i))
                {
                    //if not add new record to dictionary
                    charDictionary.Add(i, new CharacterFrequency((char)i, 1));
                }
                else
                {
                    //if so increment the frequency of this record
                    charDictionary[i].increment();
                }
                totalChars++;
            }
            read.Close();

            //Create ordered linked list of TreeNode<CharacterFrequency> objects
            OrderedLinkedList <TreeNode <CharacterFrequency> > orderedNodeList = new OrderedLinkedList <TreeNode <CharacterFrequency> >();

            //Go throughs each KeyValuePair in the CharacterFrequency dicitionary..
            foreach (KeyValuePair <int, CharacterFrequency> c in charDictionary)
            {
                //Make a new TreeNode of the CharacterFrequency value from c...
                TreeNode <CharacterFrequency> node = new TreeNode <CharacterFrequency>(c.Value);
                //add into the ordered linked list of TreeNode<CharacterFrequency>
                orderedNodeList.Add(node);
            }

            //Run a method in the binary tree to convert the ordered node list into a single node with branching children container all other nodes
            //and return and set said node as the root node of the tree
            charTree.Insert(charTree.TransferListToTree(orderedNodeList).GetFirst(), Relative.Root);

            //Run a method from the tree to return a list of BinaryPath objects
            LinkedList <BinaryPath <CharacterFrequency> > binaryTable = charTree.BinaryTable(charTree.Root);

            //Removes all nodes from the binarytable that have a null character as they cannot show up in a file
            var binary = binaryTable.First;

            while (binary != null)
            {
                var nextNode = binary.Next;
                if (binary.Value.Element.Character == '\0')
                {
                    binaryTable.Remove(binary);
                }
                binary = nextNode;
            }

            //Byte writing section

            int          bitPosition  = 7; //creates an int that determines what bit in the byte to set
            byte         y            = 0; //creates the byte to set and write with
            BinaryWriter binaryWriter = null;
            bool         error        = true;

            while (error)
            {
                try
                {
                    binaryWriter = new BinaryWriter(File.Create(CheckFile(output)));
                    error        = false;
                }
                catch (UnauthorizedAccessException ex)
                {
                    MessageBox.Show("You do not have the permissions needed to write to this folder");
                }
            }

            StreamReader streamReader = new StreamReader(input);

            //string of the entire table, to used to append to the beginning of the output file. Will be read by out in decompression process
            string tableText = String.Empty;

            //Take the total characters from the input file and append to the beginning of the output file
            tableText += totalChars + "~~~";

            //Take table and write to output file
            foreach (BinaryPath <CharacterFrequency> bp in binaryTable)
            {
                tableText += bp.Element.Character + bp.Path + ";";
            }
            binaryWriter.Write(tableText);

            //Compression process
            while (!streamReader.EndOfStream)
            {
                //Read each character from file..
                int i = streamReader.Read();
                //Find path of character from binary table...
                string path = binaryTable.FirstOrDefault(obj => obj.Element.Character == (char)i).Path;

                //Iterate through each character in path...
                foreach (char c in path)
                {
                    //If bitposition = 0  we have set all other bits
                    if (bitPosition == 0)
                    {
                        //if character is '1' set bit at bitposition in byte to 1 using bitwise OR(|)
                        if (c == '1')
                        {
                            y = (byte)(y | (byte)Math.Pow(2, bitPosition));
                        }
                        //Writes byte to output file
                        binaryWriter.Write(y);

                        //Resets byte and bitposition
                        y           = 0;
                        bitPosition = 7;
                    }
                    //If bitposition != 0
                    else
                    {
                        //if character is '1' set bit at bitposition in byte to 1 using bitwise OR(|)
                        if (c == '1')
                        {
                            y = (byte)(y | (byte)Math.Pow(2, bitPosition));
                        }
                        //progresses bitposition down 1 to next bit in byte
                        bitPosition--;
                    }
                }
            }
            //Close stream reader
            read.Close();
            //write final byte to output file and close BinaryWriter
            binaryWriter.Write(y);
            binaryWriter.Close();

            //Output to command prompt to let user know file is finished being compressied, end program
            Console.WriteLine($"File has been compressed to the file {output}");
        }