2010-08-05 4 views
1

Я пытаюсь реализовать собственный алгоритм кодирования Хаффмана и очередь приоритетов для C++ STL, похоже, работает некорректно. Я беру символы из строки и вставляю их в очередь приоритетов по порядку их частоты в строке. Код компилируется и запускается без ошибок, единственное, что дерево, похоже, не сортирует правильно. Вот код,Priority Queue Not Sorting

class Node { 
public: 
    int freq; 
    char data; 
    Node(int &f, char &d) { freq=f; data=d; } 
    bool operator<(const Node* &n) const { return n->freq < this->freq; } 
}; 

void Init(priority_queue<Node*> &tree, string input) { 
map<char,int> probability; 
for(int i=0 ; i<input.size() ; i++) { 
    probability[input[i]]++; 
} 
map<char,int>::iterator it = probability.begin(); 
for(it ; it != probability.end() ; it++) { 
    Node* blah = new Node(it->second, (char&) it->first); 
    tree.push(blah); 
} 

}

что я делаю не так?

Благодаря

ответ

8

Вы хранение указателей в priority_queue, так что элементы сортируются по значению указателя, а не с помощью перегрузки operator<.

Вам нужно либо сохранить Node объектов в очереди приоритетов, либо вам нужно написать пользовательскую функцию сравнения для очереди приоритетов, которая разыгрывает сохраненные указатели и сравнивает объекты Node, на которые они указывают.

Поскольку вы спросите: «Что я делаю неправильно ?,» Вот некоторые другие предложения:

  • Ваша перегрузка operator< должна принять константную ссылку, а не ссылка на указатель.
  • Ваш конструктор Node должен принимать свои параметры по значению или, по крайней мере, по ссылке const. Литой (char&)it->first не очень хорошо. Пусть const поможет вам написать хороший код, не сражайтесь с ним.
  • Возможно, вы должны хранить объекты Node непосредственно в очереди приоритетов, а не указатели.
  • Вы используете using namespace std где-нибудь; вы должны удалить это и указать std:: везде, где вам нужно.
+0

Хорошо, поэтому я понимаю, что оператор принимает ссылку на const, а не один указатель, а PQ принимает узлы вместо указателей на Узлы. А как же остальные? Почему конструктор должен принимать параметры по значению, почему я не должен использовать «using namespace std», и почему это отлитие типа, чтобы избавиться от неудобной практики const? – Zach

+1

@ Zach: Вы не меняете параметры, поэтому зачем передавать параметры так, как если бы вы это сделали? Если бы вы это сделали, вам не понадобится этот опасный бросок позже. Почему это опасно? Поскольку ключи карты не должны меняться; если вы измените один, карта больше не будет сортироваться, и теперь вы разбили весь контейнер. 'using namespace std;' побеждает всю цель помещать вещи в пространство имен для начала. Вы ввели всевозможные возможности для тонких ошибок из-за перегрузок, конфликтов имен и т. П. –