Алгоритм Хаффмана, реализация - C#

Узнай цену своей работы

Формулировка задачи:

Всем здравствуйте, нужна помощь в реализации алгоритма Хаффмана. Приведу пример с с++ : есть класс X с переменными a float и s string и указателями X *left, *right. создаём лист указателей list<*Х>(заполняем, в каждом объекте кл. храним символ и его частоту). Далее создаём два новых указателя X *d, X*r, сортируем лист по возрастанию, 1эл=d 2эл=r, удаляем первые два эл из листа. Создаём объект класса Х parent передаём посредством конструктора d,r, также в конструкторе вычисляем a=d.a+r.a. Parent записываем в лист. Вроде как-то так, как можно реализовать это на c#?
Сформулирую более понятно. Есть такой вот код
Листинг программы
  1. using System;
  2. using System.IO;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Data;
  6. using System.Drawing;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. using System.Windows.Forms;
  11. using System.Text.RegularExpressions;
  12. using MathNet.Numerics;
  13. using MathNet.Numerics.LinearAlgebra.Double;
  14. using MathNet.Numerics.LinearAlgebra.Solvers;
  15. using System.Collections;
  16. namespace WindowsFormsApplication1
  17. {
  18.  
  19. public partial class Form1 : Form
  20. {
  21. public Form1()
  22. {
  23. InitializeComponent();
  24. }
  25. string path;
  26. bool u;
  27. int i1, size;
  28.  
  29. private void button1_Click(object sender, EventArgs e)
  30. {
  31. float[] mas = new float[size];
  32.  
  33. List<Ver_Symbol> Ver_S = new List<Ver_Symbol>();
  34.  
  35. // List<Uzel> Uzel_ = new List<Uzel>();
  36.  
  37. Dictionary<string, float> ar = new Dictionary<string, float>();
  38. List<float> bezYsl_ver = new List<float>();
  39. List<float> Symbol2 = new List<float>();
  40. List<float> Symbol3 = new List<float>();
  41. string r;
  42.  
  43. int q = 0, h = 0, k = 0, count =1;
  44. float f;
  45. double D = 0;
  46. string b;
  47.  
  48. char[] a = new char[27] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
  49. 'J','K','L','M','N','O','P','Q','R','S','T',
  50. 'U','V','W','X','Y','Z',' '};
  51. char[] rus = new char[34] {'А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж', 'З',
  52. 'И','Й','К','Л','М','Н','О','П','Р','С','Т',
  53. 'У','Ф','Х','Ц','Ч','Ш','Щ','Ъ','Ы','Ь','Э','Ю','Я',' '};
  54.  
  55. using (StreamReader sr = new StreamReader(path))
  56. {
  57. string text = sr.ReadToEnd();
  58. char[] chars = text.ToCharArray(); // посимвольный проход по тексту
  59. if(u==true)
  60. mas = Chastota(a, chars,size);
  61. else
  62. mas = Chastota(rus, chars,size);
  63. }
  64.  
  65. richTextBox1.Text = " Частоты символов алфавита: "+"\n";
  66. for (int i = 0; i < mas.Length; i++)
  67. {
  68. if(mas[i]!=0)
  69. richTextBox1.Text +=count++ +"\t" +mas[i].ToString()+"\n";
  70. }
  71. f = mas.Sum();
  72.  
  73. for (int i = 0; i < mas.Length; i++)
  74. {
  75. if (mas[i] != 0)
  76. {
  77. bezYsl_ver.Add(mas[i]/f);
  78. }
  79. }
  80.  
  81. richTextBox1.Text += "\n Безусловная вер. символов алфавита: " + "\n";
  82.  
  83. richTextBox1.Text += "\n";
  84. for (int i = 0; i < bezYsl_ver.Count; i++)
  85. {
  86. if (u == true)
  87. {
  88. Ver_s.Add(new Ver_Symbol(a[i].ToString(), bezYsl_ver[i]));
  89. }
  90. else
  91. {
  92. Ver_s.Add(new Ver_Symbol(rus[i].ToString(), bezYsl_ver[i]));
  93. }
  94. }
  95.  
  96. for (int i = 0; i < Ver_s.Count; i++)
  97. {
  98. if (u == true)
  99. richTextBox1.Text += Ver_s[i] + "\n";
  100. else
  101. richTextBox1.Text += Ver_s[i].ToString() + "\n";
  102. }
  103.  
  104. Ver_S.Sort(delegate(Ver_Symbol mc1, Ver_Symbol mc2) // сортировка
  105. {
  106. return mc1.a.CompareTo(mc2.a);
  107. });
  108. richTextBox1.Text += "\n";
  109. for (int i = 0; i < Ver_S.Count; i++)
  110. richTextBox1.Text += Ver_S[i].s + "\t" + Ver_S[i].a + "\n";
  111.  
  112. richTextBox1.Text += "\n";
  113. while (Ver_S.Count != 1)
  114. {
  115. Ver_S.Sort(delegate(Ver_Symbol mc1, Ver_Symbol mc2) // сортировка
  116. {
  117. return mc1.a.CompareTo(mc2.a);
  118. });
  119. r = Ver_S[0].s;
  120. for (int i = 1; i < Ver_S.Count; i++) // присваиваем отсорт. лист переменной r
  121. r+=Ver_S[i].s;
  122.  
  123. // Ver_Symbol Left_ = Ver_S[0];
  124. // Ver_Symbol Right_= Ver_S[1];
  125. // Uzel parent = new Uzel(Left_, Right_);
  126. Ver_S[0].a = Ver_S[0].a + Ver_S[1].a; // суммируем минимальные элементы
  127. Ver_S[0].s = Ver_S[0].s + Ver_S[1].s;
  128. richTextBox1.Text += r + "\t\t" + Ver_S[0].s + "\t" + Ver_S[0].a; // выводим отсортированный лист и сумму мин. элементов
  129. richTextBox1.Text += "\n";
  130. ar.Add(Ver_S[0].s, Ver_S[0].a);
  131. Ver_S.RemoveAt(0);
  132. Ver_S.RemoveAt(1);
  133. // Ver_S.Add(parent);
  134. }
  135.  
  136. // foreach (var i in ar)
  137. // richTextBox1.Text += i.Key + "\t" + i.Value + "\n";
  138. richTextBox1.Text += "\n";
  139. for (int i = 0; i < Ver_S.Count; i++)
  140. richTextBox1.Text += Ver_S[i].s + "\t" + Ver_S[i].a + "\n"; // вывод основания дерева
  141.  
  142. }
  143.  
  144. private void button2_Click(object sender, EventArgs e)
  145. {
  146. OpenFileDialog openfile = new OpenFileDialog();
  147. openfile.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
  148. if (openfile.ShowDialog() == DialogResult.OK)
  149. path = openfile.FileName;
  150. }
  151. private void button3_Click(object sender, EventArgs e)
  152. {
  153. richTextBox1.Clear();
  154. textBox1.Clear();
  155. }
  156.  
  157. public static float[] Chastota(char[] alfavit, char[] chars1,int size1)
  158. {
  159. float[] mas2 = new float[size1];
  160. for (int i = 0; i < alfavit.Length; i++)
  161. {
  162. for (int j = 0; j < chars1.Length; j++)
  163. {
  164. if (alfavit[i] == Char.ToUpper(chars1[j]))
  165. {
  166. mas2[alfavit[i]]++;
  167. }
  168. }
  169. }
  170. return mas2;
  171. }
  172. private void button5_Click(object sender, EventArgs e)
  173. {
  174. u = true;
  175. size = 256;
  176. }
  177. private void button4_Click(object sender, EventArgs e)
  178. {
  179. u = false;
  180. size = 2560;
  181. }
  182.  
  183. class Ver_Symbol
  184. {
  185. public float a;
  186. public string s;
  187.  
  188. public Ver_Symbol(string ch, float number)
  189. {
  190. this.s = ch; this.a = number;
  191. }
  192. }
  193. /* class Uzel
  194. {
  195. public float a;
  196. public Ver_Symbol left;
  197. public Ver_Symbol right;
  198. public Uzel(Ver_Symbol L, Ver_Symbol R)
  199. {
  200. this.left = L; this.right = R;
  201. a = L.a + R.a;
  202. }
  203. }
  204. */
  205. }
  206. }
Код создает дерево, проходит от "листьев" к "корню", как можно реализовать проход обратно от корня к "листьям" ? Что в C# для этого использовать? В с++ это делается с помощью указателей, в шарпе указатели не применяются(
Листинг программы
  1. class Node
  2. {
  3. public:
  4. int a;
  5. char c;
  6. Node *left, *right;
  7. Node(){left=right=NULL;}
  8. Node(Node *L, Node *R)
  9. { left = L;
  10. right = R;
  11. a = L->a + R->a; }
  12. };
  13. void BuildTable(Node *root)
  14. {
  15. if (root->left!=NULL)
  16. { code.push_back(0);
  17. BuildTable(root->left);}
  18. if (root->right!=NULL)
  19. { code.push_back(1);
  20. BuildTable(root->right);}
  21. if (root->left==NULL && root->right==NULL) table[root->c]=code;
  22. code.pop_back();
  23. }
  24. ////// записываем начальные узлы в список list
  25. list<Node*> t;
  26. for( map<char,int>::iterator itr=m.begin(); itr!=m.end(); ++itr)
  27. {
  28. Node *p = new Node;
  29. p->c = itr->first;
  30. p->a = itr->second;
  31. t.push_back(p); }
  32.  
  33. ////// создаем дерево
  34. while (t.size()!=1)
  35. {
  36. t.sort(MyCompare());
  37. Node *SonL = t.front();
  38. t.pop_front();
  39. Node *SonR = t.front();
  40. t.pop_front();
  41. Node *parent = new Node(SonL,SonR);
  42. t.push_back(parent);
  43. }
  44. Node *root = t.front(); //root - указатель на вершину дерева
  45. ////// создаем пары 'символ-код':
  46. BuildTable(root);

Решение задачи: «Алгоритм Хаффмана, реализация»

textual
Листинг программы
  1. class Node
  2. {
  3.     public:
  4.      int a;
  5.      char c;
  6.      Node *left, *right;
  7.      
  8.      Node(){left=right=NULL;}
  9.  
  10.      Node(Node *L, Node *R)
  11.      {  left =  L;
  12.         right = R;
  13.         a = L->a + R->a;  }
  14. };

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

15   голосов , оценка 4.333 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут