【问题标题】:huffman algorithm霍夫曼算法
【发布时间】:2012-06-15 19:04:02
【问题描述】:

我正在 HUFFMAN ALGORITHM 上制作一个程序,其中我有一类节点 (hnode) 来包含符号 (name ) 及其出现频率 (freq);和其他类 (pq),用于形成 tree 以获取符号的代码。我只写了课程的相关部分。现在,当我尝试运行这个程序时,当它第二次进入 while 循环 时,它总是卡在 while 循环中(in main())。我已经尝试了所有方法,但仍然无法弄清楚为什么......有人可以帮助让这段代码运行!

#define NPTR hnode*
class pq;
class hnode
{
    string name;
    int freq;
    friend class pq;

    public:

    NPTR phnode;
    void show () 
    { cout << "name = " << name << endl << ", freq= " << freq <<endl ; }

    hnode (string x, int fr): name(x), freq(fr)
    {
        phnode = this;
    }

    friend hnode operator + (hnode p, hnode q)
    {
        string s = q.name + p.name;
        int f = q.freq + p.freq ;
        hnode foo (s,f);
        return foo;
    }
};

class pq /// ascending priority queue
{
    struct node
    {
    NPTR data;
    node* next;
    node (NPTR p) : data(p), next(0) {}
    };
    public:
    int count;
    node* getnode (NPTR p) { return new node(p); }
    node* listptr;
    void place (NPTR );
    NPTR mindelete();
    pq() : listptr(0), count(0) {}
};

void pq::place (NPTR p)
{
    if(count == 0)
    {
        listptr = getnode(p);
    }

    else
    {
        node* foo = listptr, *bar = NULL;
        while( (foo!= NULL) && (p->freq >= foo->data->freq) )
        {
            bar = foo;
            foo = foo->next;
        }
        node* ptr = getnode(p);
        ptr->next = bar->next;
        bar->next = ptr;
    }
    ++count;
}

NPTR pq::mindelete()
{
    if(count==0) { cout<<"invalid\n"; exit(1);}
    NPTR val = listptr->data;
    listptr = listptr->next;
    --count;
    return val;
}

void main ()
{
    pq list;
    for ( int i=0; i<3; ++i)
    {
        string s;
        int f;
        cin>>s>>f;
        NPTR p = new hnode(s,f);
        list.place(p);
    }
    while(list.count>1)
    {
        NPTR p1 = list.mindelete();
        NPTR p2 = list.mindelete();
        hnode po = (*p1)+(*p2); // overloaded operator
        NPTR p = &po;
        p->show();
        list.place(p);
    }
}

【问题讨论】:

  • 你试过使用调试器吗?
  • 其实不是我自己做的,但我认为编译器是为我做的。
  • 我不确定我们对调试器的定义是否相同...en.wikipedia.org/wiki/Debugger
  • 如果循环中只有带有 '.mindelete' 和 '.place' 的行,那么上面的代码就可以很好地退出循环。这暗示了一些缺失的逻辑。如果你不明白哪里出了问题,就很难确定什么是相关的。

标签: c++ class huffman-code


【解决方案1】:

您的代码在这里创建了一个本地范围的hnode po

while(list.count > 1)
{
    NPTR p1 = list.mindelete();
    NPTR p2 = list.mindelete();
    hnode po = (*p1)+(*p2); // overloaded operator
    NPTR p = &po;
    p->show();
    list.place(p);
}

然后你通过地址传递它,你让pq::node 坚持下去。听起来是个非常糟糕的主意,因为 hnode po 在每次迭代的 while 循环结束时超出范围

一般来说,您希望使用智能点和 RAII 进行自动内存管理,而不是到处进行新建和删除。

【讨论】:

  • 谢谢维克多。这正是它被卡住的地方。我修改了 + 运算符,在那里在堆上创建了一个对象并返回了一个指向该对象的指针,将它存储在 while 循环中的 NPTR p 中,现在它运行良好:)
【解决方案2】:

我建议看看这里:

NIST adaptive Huffman

还有这里:

NIST Huffman

也可以在此处找到代码示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多