【问题标题】:Huffman Tree, Wrong Encoding霍夫曼树,错误的编码
【发布时间】:2014-11-28 12:34:28
【问题描述】:

当我完成我的树时我很高兴,但我遇到了编码问题。最常见的字符没有得到最短的二进制代码。我的猜测是递归遍历函数或节点列表的初始化有问题

主程序:

public partial class MainWindow : Window
{
    string kode;

    public MainWindow()
    {
        InitializeComponent();
        kode = "";
    }

    public double forhold(int input, int komprimert)
    {
        int tall1 = input * 8;
        int tall2 = komprimert;
        return ((double)tall1 / (double)tall2);
    }

    public void Traverser(Node rot, string kode) //Traverse the tree
    {
        if (rot != null) 
        {
            if (rot.Venstre != null) //If the current node has a left child
            {
                 Traverser(rot.Venstre, kode+"0");
            }
            if (rot.Høyre!= null) //If the current node has a right child
            {
                 Traverser(rot.Høyre, kode+"1");
            }
            //Viser karakter med koresponderende binær kode
            if (rot.Venstre == null && rot.Høyre == null) //If the current node is a leaf
            {
                rot.kode = kode; 
                txtOutput.Text += rot.Tegn.ToString() + ": " + kode +", ";
            }
        }
    }
    //public Node FåKodeMed // 

    public void btnKomprimer_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        string input = txtInput.Text;
        bool funnet; //Found
        char karakter; //Character
        int komprimertLengde; //Not important
        txtOutput.Text = ""; 
        komprimertLengde = 0;

        if (input.Length == 0)  
        {
            txtOutput.Text = "Du må skrive noe i tekst feltet!";
        }
        else
        {
            if (input.Length == 1)
            {
                txtOutput.Text = "0";
            }
            if (input.Distinct().Count() == 1)
            {
                foreach (char c in input)
                {
                    txtOutput.Text += "0";
                }
            }
            else
            {

                List<Node> noder = new List<Node>(); //List containing nodes
                for (int i = 0; i < input.Length; i++) //Places nodes in the tree
                {
                    karakter = input[i];
                    funnet = false;
                    for (int j = 0; j< noder.Count; j++)
                    {
                        if (noder[j].erTegn(karakter) == false) //Hvis tegnet allerede eksisterer
                        {
                            noder[j].økMed1();
                            funnet = true;
                            break;
                        }
                    }
                    if (!funnet)
                    {
                        noder.Add(new Node(karakter));
                    }
                }

                //Sorter listen etter frekvens:
                var sortertListe = noder.OrderBy(c => c.Frekvens).ToList(); //Sort the list by frequency

                //noder = sortertListe;

                do
                {
                    noder.Add(new Node((noder[0].Frekvens + noder[1].Frekvens),noder[0],noder[1])); //Parent node
                    noder.RemoveAt(0);
                    noder.RemoveAt(0);
                    noder.OrderBy(c => c.Frekvens).ToList();

                }while(noder.Count >= 2);

                Node rot = new Node(noder[0]);

                Traverser(rot, "");

                //Feilen kan ligge her
                List<string> output = new List<string>(); 
                foreach (char c in input)
                {
                    for (int i = 0; i < sortertListe.Count;i++)
                    {
                        if(sortertListe[i].Tegn == c)
                        {
                            output.Add(sortertListe[i].kode);
                            break;
                        }
                    }
                }
                txtOutput.Text += "\n" + "\n";
                foreach (string s in output)
                {
                    txtOutput.Text += s;
                }

                foreach (string c in output)
                {
                    komprimertLengde += c.Length;
                }

                txtOutput.Text += "\n" + "\n";
                txtOutput.Text += "lengde på input: " + Convert.ToString((input.Length * 8)) + "\n";
                txtOutput.Text += "Lengde på komprimert: " + Convert.ToString(komprimertLengde) + "\n";
                txtOutput.Text += "Forholdet: " + Convert.ToString(forhold(input.Length,komprimertLengde));

                noder.Clear();
            }
        }
    }

节点类:

public class Node
{
    public int Frekvens {get;set;}
    public string kode {get;set;}
    public char Tegn {get;set;}
    public Node Høyre {get;set;}
    public Node Venstre {get;set;}

    public Node(char c)
    {
        Frekvens = 1;
        Tegn = c;   
    }
    public Node(Node n)
    {
        Tegn = n.Tegn;
        Frekvens = n.Frekvens;
        Venstre = n.Venstre;
        Høyre = n.Høyre;

    }
    public Node (int f, Node v, Node h)
    {
        Frekvens = f;
        Venstre = v;
        Høyre = h;
    }
    public void økMed1 ()
    {
        Frekvens = Frekvens + 1;
    }
    public bool erTegn(char c)
    {
        if ( c == Tegn)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
}

【问题讨论】:

  • 提示:如果您打算向任何人显示您的来源,请在您的代码中使用英文标识符 - 无论您的国籍如何。我没有挪威语键盘,所以如果我想修改您的代码,我无法轻松输入标识符“Høyre”。此外,使用非英语标识符更难分析您的代码。
  • noder.OrderBy(c =&gt; c.Frekvens).ToList(); - 不应该是noder = noder.OrderBy(c =&gt; c.Frekvens).ToList();吗?
  • @Spook 是的,Spook,你完全正确。我决定从现在开始我会用英文写所有变量名:D
  • @500-InternalServerError 是的,当然,愚蠢的错误

标签: c# binary-tree traversal huffman-code


【解决方案1】:

我认为这里at your other question 已经提供了整个解决方案。

您的代码的问题主要是由于您的排序列表实际上以错误的顺序排序。您可能想使用

.OrderByDescending

不过,您也可以尝试其他解决方案。例如,考虑实现一个优先级队列。

注意:下次请使用英文,即使谷歌翻译也会让我感到困惑:-)

【讨论】:

  • 是的,谢谢您的回答!我们实际上在我的学校用挪威语进行所有变量命名(我认为这不是很好的编程习惯),但在过去的几个月里,我强迫自己用英语写所有东西=)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-18
相关资源
最近更新 更多