Ejemplo n.º 1
0
        public HuffmanTree(FrequencyDictionary frequencyDictionary)
        {
            Frequencies = new FrequencyDictionary();
            Frequencies = frequencyDictionary;

            //var startTime = System.Diagnostics.Stopwatch.StartNew();

            BuildTree(Frequencies);

            //startTime.Stop();
            //var resultTime = startTime.Elapsed;
            //string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:000}",
            //        resultTime.Hours,
            //        resultTime.Minutes,
            //        resultTime.Seconds,
            //        resultTime.Milliseconds);
            //Console.WriteLine("Build tree:  " + elapsedTime);

            //startTime = System.Diagnostics.Stopwatch.StartNew();

            BuildCodeTable(Frequencies);

            //startTime.Stop();
            //resultTime = startTime.Elapsed;

            //elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:000}",
            //        resultTime.Hours,
            //        resultTime.Minutes,
            //        resultTime.Seconds,
            //        resultTime.Milliseconds);
            //Console.WriteLine("Build code table:  " + elapsedTime);
            //BuildCodeTable(Frequencies);
        }
Ejemplo n.º 2
0
        public void Decode(string fileNameSource, string fileNameDecode)
        {
            BitArray bitArray = null;

            try
            {
                bitArray = new BitArray((File.ReadAllBytes(fileNameSource)));
            }
            catch (Exception exc)
            {
                throw exc;
            }
            //считываем длину битов декодировочной таблицы
            BitArray numBitCodeTable = new BitArray(32);

            for (int i = 0; i < 32; i++)
            {
                numBitCodeTable[i] = bitArray[i];
            }
            byte[] num = new byte[4];
            numBitCodeTable.CopyTo(num, 0);
            int lenTable = BitConverter.ToInt32(num, 0);

            Frequencies = GetFrequencyDictionaryFromFile(bitArray, 32, lenTable + 32);
            BuildTree(Frequencies);
            Decode(bitArray, lenTable + 32, fileNameDecode);
        }
        /// <summary>
        /// Кодирование блока слов
        /// </summary>
        /// <param name="words">Блок слов определённого размера</param>
        /// <returns>Закодированый блок представленный списком битов</returns>
        public List <bool> EncodeBlock(List <string> words)
        {
            List <bool> encodedSource = new List <bool>();
            //Составляем частотный словарь из блока слов
            FrequencyDictionary frequencyDictionary = new FrequencyDictionary(words);
            //Строим дерево по полученому словарю
            HuffmanTree huffmanTree = new HuffmanTree(frequencyDictionary);

            //Кодируем блок
            encodedSource = huffmanTree.EncodeBlock(words);
            //добавляем таблицу для декодировки
            List <bool> table = huffmanTree.GetBitArrayTable(frequencyDictionary);
            //получаем длину таблицы в виде массиве байтов
            //byte[] lenTable = BitConverter.GetBytes(table.Count);
            List <bool> lenghtTable = BitOperations.Int32ToListBool(table.Count);

            lenghtTable.AddRange(table);
            table = lenghtTable;
            //Добавляем код
            table.AddRange(encodedSource);
            //Получаем длину всего закодированного блока
            List <bool> lenghtAll = BitOperations.Int32ToListBool(table.Count);

            //добавляем эту длину в в начало блока
            lenghtAll.AddRange(table);

            encodedSource = lenghtAll;
            //возращаем закодированный блок
            return(encodedSource);
        }
        //public string DecodeBlock(string fileNameEncode)
        //{
        //    BitArray bitArray = null;
        //    try
        //    {
        //        bitArray = new BitArray((File.ReadAllBytes(fileNameEncode)));
        //    }
        //    catch (Exception exc)
        //    {
        //        throw exc;
        //    }
        //    string text = "";

        //    int indexStart = 0;

        //    while(indexStart < bitArray.Count)
        //    {
        //        text += DecodeBlock(bitArray, indexStart, out indexStart);
        //    }

        //    return text;
        //}

        public string DecodeBlock(BitArray bits, int indexStart, out int indexStop)
        {
            int    index     = indexStart;
            string textBlock = "";
            //Извдекаем всю длину блока вместе с диной
            //таблицы и последовательности кодов
            int lenAllBlock = HuffmanTree.GetIntFromBitArray(index, bits);

            index += sizeByte * sizeof(int);
            //Извлекаем длину таблицы
            int lenTable = HuffmanTree.GetIntFromBitArray(index, bits);

            index += sizeByte * sizeof(int);
            //получае частотный словарь с блока
            FrequencyDictionary frequencyDictionary = HuffmanTree.GetFrequencyDictionaryFromFile(bits, index, index + lenTable);

            index = index + lenTable;
            //получаем дерево и декодировучныю таблицу
            HuffmanTree huffmanTree = new HuffmanTree(frequencyDictionary);

            //Декодируем блок
            textBlock = huffmanTree.DecodeBlock(bits, index, index + ((lenAllBlock) - (lenTable + sizeof(int) * sizeByte)));
            indexStop = index + ((lenAllBlock) - (lenTable + sizeof(int) * sizeByte));
            //indexStop = lenAllBlock + sizeof(int) * sizeByte;

            return(textBlock);
        }
Ejemplo n.º 5
0
 public void BuildCodeTable(FrequencyDictionary frequencyDictionary)
 {
     CodeTable = new Dictionary <string, List <bool> >();
     foreach (var wordNode in nodesDictionary)
     {
         List <bool> encodedWord = GetCode(wordNode.Value); //Root.Traverse(word.Key, new List<bool>());
         CodeTable.Add(wordNode.Key, encodedWord);
     }
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Получить вектор с честотами для блока слов
        /// </summary>
        /// <param name="frequencyDictionary">Словарь всех слов текста</param>
        /// <param name="words">Блок слов</param>
        /// <returns>Вектор, с частотами слов в блоке</returns>
        public static Dictionary <string, double> GetVectorFrequencyFromBlock(FrequencyDictionary frequencyDictionary, List <string> words)
        {
            //Получаем нулевой вектор
            Dictionary <string, double> vector = GetVectorZerosFromFrequencyDictionary(frequencyDictionary);

            //подсчитываем количество слов
            foreach (var word in words)
            {
                vector[word] += 1;
            }

            List <string> keys = new List <string>(vector.Keys);

            //получаем частоту
            foreach (var item in keys)
            {
                vector[item] /= words.Count;
            }
            return(vector);
        }
Ejemplo n.º 7
0
        public void BuildTree(FrequencyDictionary frequencyDictionary)
        {
            foreach (KeyValuePair <string, int> word in frequencyDictionary.Dictionary)
            {
                nodes.Add(new NodeHT()
                {
                    Word = word.Key, Frequency = word.Value
                });
                nodesDictionary.Add(word.Key, nodes.Last());
            }

            while (nodes.Count > 1)
            {
                List <NodeHT> orderedNodes = nodes.OrderBy(node => node.Frequency).ToList <NodeHT>();

                if (orderedNodes.Count >= 2)
                {
                    // Take first two items
                    List <NodeHT> taken = orderedNodes.Take(2).ToList();

                    // Create a parent node by combining the frequencies
                    NodeHT parent = new NodeHT()
                    {
                        Word      = "",
                        Frequency = taken[0].Frequency + taken[1].Frequency,
                        Left      = taken[0],
                        Right     = taken[1]
                    };
                    taken[0].Parent = parent;
                    taken[1].Parent = parent;

                    nodes.Remove(taken[0]);
                    nodes.Remove(taken[1]);
                    nodes.Add(parent);
                }

                Root        = nodes.FirstOrDefault();
                Root.Parent = null;
            }
        }
Ejemplo n.º 8
0
 public HuffmanTree()
 {
     nodes       = new List <NodeHT>();
     Root        = null;
     Frequencies = new FrequencyDictionary();
 }
Ejemplo n.º 9
0
        public List <bool> GetBitArrayTable(FrequencyDictionary frequencyDictionary)
        {
            List <bool> res = new List <bool>();

            byte lenBitWord = 0x00;

            foreach (var item in frequencyDictionary.Dictionary)
            {
                lenBitWord = (byte)item.Key.Length;
                for (int i = 0; i < 8; i++)
                {
                    if (((lenBitWord << i) & maskForEncode) == 0x00)
                    {
                        res.Add(false);
                    }
                    else
                    {
                        res.Add(true);
                    }
                }

                byte[] wordByteArray = Encoding.Default.GetBytes(item.Key);
                foreach (var symbol in wordByteArray)
                {
                    for (int i = 0; i < 8; i++)
                    {
                        if ((byte)((symbol << i) & maskForEncode) == 0x00)
                        {
                            res.Add(false);
                        }
                        else
                        {
                            res.Add(true);
                        }
                    }
                }

                byte[] buf  = BitConverter.GetBytes(item.Value);
                byte[] freq = new byte[4];
                freq = buf;
                //for (int i = 0; i < buf.Length; i++)
                //{
                //    freq[i] = buf[buf.Length - 1 - i];
                //}


                foreach (var b in freq)
                {
                    for (int i = 0; i < 8; i++)
                    {
                        if (((b << i) & maskForEncode) == 0x00)
                        {
                            res.Add(false);
                        }
                        else
                        {
                            res.Add(true);
                        }
                    }
                }
            }
            //if(codeTableBit.Count % 8 == 0)
            return(res);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Получение нулевого вектора, для текста
        /// </summary>
        /// <param name="frequencyDictionary">Частотный словарь по всему тексту</param>
        /// <returns>Нулевой вектор, где каждое слово ассоциируется с конкретной позицией в векторе</returns>
        public static Dictionary <string, double> GetVectorZerosFromFrequencyDictionary(FrequencyDictionary frequencyDictionary)
        {
            Dictionary <string, double> vector = new Dictionary <string, double>();

            //Отсортируем по частоте встречания слова
            frequencyDictionary.SortDescValue();
            //Вормируем ассоциативный 0-вектор
            foreach (var item in frequencyDictionary.Dictionary)
            {
                vector.Add(item.Key, 0.0);
            }
            return(vector);
        }
        /// <summary>
        /// Кодирование исходного текста блочным способом c использованием метрики
        /// </summary>
        /// <param name="fileNameSource">Имя файла исходного текста</param>
        /// <param name="sizeBlock">Размер блока</param>
        /// <returns>Закодированый текст блочным методом с использованием метрики, представленный в виде списка битов</returns>
        public List <bool> EncodeBlockWithMetrics(string fileNameSource, int sizeBlock,
                                                  out List <double> distanсeEuclide, out List <double> distanceChebyshev, out List <double> distanceCityBlock)
        {
            FrequencyDictionary frequencyDictionary = new FrequencyDictionary(fileNameSource);

            Dictionary <string, double> p = ComparisonVector.GetVectorZerosFromFrequencyDictionary(frequencyDictionary);
            Dictionary <string, double> q = ComparisonVector.GetVectorZerosFromFrequencyDictionary(frequencyDictionary);

            List <double> distanceE  = new List <double>();
            List <double> distanceC  = new List <double>();
            List <double> distanceCB = new List <double>();

            //Открываем поток для считывания с файла
            StreamReader fileRead      = new StreamReader(@fileNameSource, Encoding.Default);
            List <bool>  encodedSource = new List <bool>();
            //Считываем весь текст с файла
            string text = fileRead.ReadToEnd();
            //int indexText = 0;
            int indexBegin = 0;
            int indexEnd   = 0;

            //пока не конец текста
            while (indexEnd < text.Length)
            {
                //indexBegin = 0;
                //indexEnd = 0;
                List <string> listWords = new List <string>();
                //идём по тексту, пока не наберём слов количеством в размер блока и пока не конец текста
                for (int i = 0; (i < sizeBlock) && (indexEnd < text.Length); i++)
                {
                    //пока это буква увеличиваем индекс конца слова
                    while (indexEnd < text.Length && char.IsLetter(text[indexEnd])

                           /*((text[indexEnd] >= 'a' && text[indexEnd] <= 'z') ||
                            * (text[indexEnd] >= 'A' && text[indexEnd] <= 'Z')) ||
                            * ((text[indexEnd] >= 'а' && text[indexEnd] <= 'я') ||
                            * (text[indexEnd] >= 'А' && text[indexEnd] <= 'Я'))*/)
                    {
                        indexEnd++;
                    }
                    //если мы прошлись по слову
                    string word;
                    if (indexBegin != indexEnd)
                    {
                        word = text.Substring(indexBegin, indexEnd - indexBegin);
                    }
                    else //это знак препенания, пробел или знак табуляции
                    {
                        indexEnd++;
                        word = text.Substring(indexBegin, indexEnd - indexBegin);
                    }
                    indexBegin = indexEnd;
                    //добавляем слово в блок
                    listWords.Add(word);
                }
                //кодирум блок слов и добавляем получившиеся биты в список битов
                encodedSource.AddRange(EncodeBlock(listWords));

                //работа с растояниями
                q = ComparisonVector.GetVectorFrequencyFromBlock(frequencyDictionary, listWords);
                distanceE.Add(ComparisonVector.GetEuclideanDistance(p, q));
                distanceC.Add(ComparisonVector.GetChebyshevDistance(p, q));
                distanceCB.Add(ComparisonVector.GetCityBlockDistance(p, q));
                p = q;
            }

            //for (int i = 0; i < distanceE.Count; i++)
            //{
            //    Console.Write(distanceE[i].ToString() + " " +  distanceC[i].ToString() +
            //        " " + distanceCB[i].ToString() + "\n");
            //}

            distanсeEuclide   = distanceE;
            distanceChebyshev = distanceC;
            distanceCityBlock = distanceCB;

            //возращаем закодированный блок слов в виде списка бит
            return(encodedSource);
        }