Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Προσπαθώ να χρησιμοποιήσω το std::priority_queue με δικο μου αντικειμενο αλλα κάτι κανω λαθος.

Εχω εναν τύπο Label<T> οπου εχει καποιες τιμες που κατατάσσονται με "αλφαβητικο"  τροπο.

Παράδειγμα ενα Label<int> μεγεθους 3 θα ηταν το {3, 5, 6}, και ειναι μεγαλύτερο απο το {2, 10, 1}, αλλα μικρότερο απο το {3, 6, 1}.

 

Εχω ορίσει στην Label τους τελεστές σύγκρισης:

 

bool operator >(const Label<T> &other) const;
bool operator <(const Label<T> &other) const;
bool operator ==(const Label<T> &other) const;
bool operator >=(const Label<T> &other) const;
bool operator <=(const Label<T> &other) const;

 

Και έχω δοκιμάσει οτι δουλεουν κανονικά.

 

Ορίζω λοιπόν το priority_queue, βάζω κάποιες τιμες και προσπαθώ να τυπώσω:

 

 

 

std::priority_queue<Label<int>, vector<Label<int>>, std::less<Label<int>> > f;
 
//push some labels 
Label<int> c(2);
c[0] = 7;
c[1] = 7;

f.push(l);
//κτλ κτλ


for(int i = 0; i < 6; i++)
{
cout << f.top().printLabel() << endl;
f.pop();
} 

 

 

 

Αλλά όταν πάω να το τρέξω πετάει error:

Unhandled exception at 0x7787e3be in program.exe: 0xC0000005: Access violation reading location 0xdecc6f56.

 

Τι κάνω λαθος;

  • Moderators
Δημοσ.

Υποθέτω λόγω του "κτλ κτλ" ότι κάνει πολλά f.push(αντικείμενα Label). Μάλλον έχει ξεφύγει το l εκεί.

 

 

 

for(int i = 0; i < 6; i++)
{
cout << f.top().printLabel() << endl;
f.pop();
} 

 

Αυτό το for loop το κάνεις για τα 6 στοιχεία που έχεις περάσει στην queue? Γιατί όχι ένα while( !f.empty() )

Η printLabel() τι επιστρέφει;

Δημοσ.

Ναι push(c ) ηθελα, απλα αφησα 1 απο τα 6 push και εσβησα λαθος push :P

Απλα δοκιμαστικο ηταν για αυτο απλα κανει ενα for μεχρι το 6.

Η printLabel επιστρέφει ενα string για τo Label με αυτη τη μορφη: {a, b, c}

Δημοσ.

Σε αυτον ισχυει αυτο

"but the criterion how they are sorted is not included in the elements itself, but somewhere different, like in a map:", αλλα σε εμένα οι τελεστές συγκρισης ειναι ορισμενοι, οπότε δεν υπαρχει αυτο το θεμα.

Δημοσ.

Αλλαξα την δηλωση του queue σε

std::priority_queue<Label<int>*, vector<Label<int>*>, std::less<Label<int>*> > f;
//...
f.push(&label);

Και τώρα τρέχει, αλλα δεν τα ταξινομεί σωστά. Λογικα συγκρινει της θεσεις μνήμης των αντικειμενων.

 

Το debug στον αρχικο κωδικα μου εβγαζε debug assertion failed σε άλλα αρχεία απο τα δικά μου και δεν εχω ιδεα τι σημαινει.

 

edit:

Το έφτιαξα τελικα, αλλάζοντας την δήλωση σε

 
std::priority_queue<Label<int>*, vector<Label<int>* >, decreasingOrderLabel > pq;
 
οπου decreasingOrderLabel είναι το 
 
 
struct decreasingOrderLabel
{
bool operator() (const Label<int> * lhs, const Label<int> * rhs) const
{
return *lhs > *rhs;
}
}; 

Δεν εχω ομως ακομα καταλάβει τι έπαιζε στο αρχικο παράδειγμα...

Δημοσ.

Εαν δουλευει με pointer τοτε εχεις προβλημα με τον copy ή τον move constructor. Βεβαια αν δε δω το imp του label, ολα αυτα που λεω ειναι απλες "μαντεψιες".

Δημοσ.

(το copy paste χαλαει τα tabs, αλλα ελπιζω να μην ειναι μεγαλο προβλημα στην αναγνωση)

 

 

 

 
#pragma once

#include <string>
#include <sstream>
using std::string;
using std::stringstream;

template <typename T> class Label
{
private:
int size;
T* criteria;

public:
Label(int size);
~Label();

int getSize() const { return size; };

T & operator [](int index);
T getCriteria(int index) const;

bool operator >(const Label<T> &other) const;
bool operator <(const Label<T> &other) const;
bool operator ==(const Label<T> &other) const;
bool operator >=(const Label<T> &other) const;
bool operator <=(const Label<T> &other) const;


string printLabel();
};

template <typename T> Label<T>::Label(int size)
{
this->size = size;

criteria = new T[size];

for(int i = 0; i < size; i++)
{
criteria[i] = T();
}
}

template <typename T> Label<T>::~Label()
{
delete[] criteria;
}

template <typename T> T & Label<T>::operator [](int index)
{
if(index < 0 || index >= size)
throw -1;

return criteria[index];
}

template <typename T> T Label<T>::getCriteria(int index) const
{
if(index < 0 || index >= size)
throw -1;

return criteria[index];
}

template <typename T> bool Label<T>::operator >(const Label<T> &other) const
{
if (this->size != other.getSize())
return false;

for(int i = 0; i < size; i++)
{
if(this->criteria[i] > other.getCriteria(i))
return true;
else if(this->criteria[i] < other.getCriteria(i))
return false;
}

return true;
}

template <typename T> bool Label<T>::operator <(const Label<T> &other) const
{
return !(*this > other);
}

template <typename T> bool Label<T>::operator ==(const Label<T> &other) const
{
if (this->size != other.getSize())
return false;

for(int i = 0; i < size; i++)
{
if(this->criteria[i] != other.getCriteria(i))
return false;
}

return true;
}

template <typename T> bool Label<T>::operator >=(const Label<T> &other) const
{
return (*this > other) || (*this == other);
}

template <typename T> bool Label<T>::operator <=(const Label<T> &other) const
{
return (*this < other) || (*this == other);
}


template <typename T> string Label<T>::printLabel()
{
stringstream stream;

stream << "{";

for (int i = 0; i < size; i++)
{
stream << criteria[i];

if(i < size - 1)
stream << ",";
}

stream << "}";

return stream.str();
}
 

 

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...