Anzahl gleicher Elemente mit equal_range berechnen



  • Ich hoffe ich frage bzw. erstelle jetzt zum letzten Mal was zu diesem Beispiel:

    Also die Frage lautet folgendermaßen:
    Bestimmen Sie mit Hilfe von std::equal_range die Häufigkeit der Zufallszahlen im Container
    und geben Sie diese ebenfalls aus:

    Nach Recherche (die Übung besteht fast nur aus Eigenrecherche von dieser Seite:
    http://www.cplusplus.com/reference/algorithm/equal_range{), gibt mir equal range einen pair von zwei Positionen zurück. Um die Anzahl der gleichen Elemente muss ich also das stl-algo distance benutzen

    Nun zu meinem Code:

    Element ist hier eine Klasse und Elementvector ist ein typedef für einen Vektor aus Element):

    void FindEqual(Elementvector const & vect)
    {
    	pair<vector<Element>::iterator,vector<Element>::iterator> range;
    
    	for (int i=0; i!=vect.size(); i++)
    	{
    		range=equal_range(vect.begin(),vect.end(),vect[0].ngen);
    		vector<Element>::difference_type n = distance(range.first, range.second);
    
    		cout <<"random number ("<<vect[i]<<") :" << n;
    	}
    }
    

    Doch bekomme ich folgende Fehlerbombe:
    http://www.imagenetz.de/ff897f3ac/unbenannt.PNG.html

    WÜrde mich fruen, falls wer statt den Feirtag zu genießen, mir helfen würde 😃 :p 🙂

    mfg
    ACnut



  • Da 'vect' eine Referenz auf ein konstantes Objekt ist, mußt du auch den const_iterator benutzen:

    vector<Element>::const_iterator
    


  • zwei Fehler weniger, danke 🙂

    jetzt sieht es aber so aus
    http://www.imagenetz.de/f13ea4222/unbenannt.PNG.html

    wozu brauche ich bitte den <-operator? ich vergleiche ja nur auf gleichheit?

    was genau wird mit den deduce+<-operator-fehlern gemeint?



  • Ganz einfach: Wahrscheinlich in equal_range wird upper_bound aufgerufen, und in upper_bound wird ein Vergleich zwischen zwei Objekten vom Typ Element gemacht.
    Da du aber die entsprechenden Operator nicht überladen hast, gibt es einen Fehler.

    Weiß ich aber nicht genau, ich hab nicht die Header von VC++.





  • man seit ihr gut 🕶
    ihr habt recht, hätte genauer recherchieren müssen 👍

    jetzt habe ich aber einen type-mismatch:

    Error 1 error C2678: binary '<' : no operator found which takes a
    left-hand operand of type 'const int' (or there is no acceptable conversion)
    c:\program files (x86)\microsoft visual studio 10.0\vc\include
    \algorithm 2890

    bool operator <(const Element& E, const Element &R)
    {
    	if (E.ngen < R.ngen)
    		return true;
    	else return false;
    	return false;
    }
    

    wo muss ich hier den const noch schreiben?



  • ACnut schrieb:

    man seit ihr gut 🕶
    ihr habt recht, hätte genauer recherchieren müssen 👍

    jetzt habe ich aber einen type-mismatch:

    Error 1 error C2678: binary '<' : no operator found which takes a
    left-hand operand of type 'const int' (or there is no acceptable conversion)
    c:\program files (x86)\microsoft visual studio 10.0\vc\include
    \algorithm 2890

    bool operator <(const Element& E, const Element &R)
    {
    	if (E.ngen < R.ngen)
    		return true;
    	else return false;
    	return false;
    }
    

    wo muss ich hier den const noch schreiben?

    Der Operator ist hübsch.
    Aber ich hätte friend davorgeschrieben, damit er zur freien Funktion außerhalb der Klasse wird.



  • bool operator <(const Element& E, const Element &R) 
    { 
        if (E.ngen < R.ngen) 
            return true; 
        else return false; 
        return false; 
    }
    

    ➡

    bool operator <(const Element& E, const Element &R) 
    { 
        return E.ngen < R.ngen; 
    }
    


  • range=equal_range(vect.begin(),vect.end(),vect[0].ngen);
    

    soll vermutlich

    range=equal_range(vect.begin(),vect.end(),vect[0]);
    

    sein.



  • volkard vielen dank

    wenn ich die funktion als friend definiere muss ich die methode auch in der klasse haben?

    offtopic: wann muss ich die operatorüberladung innerhalb der klasse haben, denn bis jetzt hab ich es immer außerhalb geschrieben

    mfg
    ACnut



  • ACnut schrieb:

    volkard vielen dank

    wenn ich die funktion als friend definiere muss ich die methode auch in der klasse haben?

    offtopic: wann muss ich die operatorüberladung innerhalb der klasse haben, denn bis jetzt hab ich es immer außerhalb geschrieben

    mfg
    ACnut

    Außerhalb ist gut.
    Als friend darf man sie innerhalb schreiben, sie ist aber dann auch in Wirklichkeit außerhalb.

    Innerhalb würde der Operator den linken Parameter implizit als *this mitkriegen und in den Parameterklammern würde nur noch die rechte Seite stehen. Das ist unhübsch. Und manchmal sogar schlecht.



  • ah gut zu wissen 🙂

    das heißt innerhalb der klasse würde die funktion so aussehen?

    bool Element:: operator <(const Element& E)
    {
        Element blabla(*this);
        return blabla.ngen < E.ngen;
    }
    


  • bool Element::operator <(const Element& E)
    {
        return (*this).ngen < E.ngen;
    }
    

    oder

    bool Element::operator <(const Element& E)
    {
        return this->ngen < E.ngen;
    }
    

    oder

    bool Element::operator <(const Element& E)
    {
        return ngen < E.ngen;
    }
    

    oder

    bool Element:: operator <(const Element& E)
    {
        Element& blabla=*this;
        return blabla.ngen < E.ngen;
    }
    


  • ACnut schrieb:

    ah gut zu wissen 🙂

    das heißt innerhalb der klasse würde die funktion so aussehen?

    bool Element:: operator <(const Element& E)
    {
        Element blabla(*this);
        return blabla.ngen < E.ngen;
    }
    

    Die Qualifizierung mit dem Klassennamen (Element::) musst du weglassen, das muss eine unqualified-id sein.

    Die Variante mit der Operatorfunktion als Memberfunktion hat einen Nachteil: Falls die Klasse, für die der Operator überladen wird, einen Konvertierungskonstruktor bereitstellt, kann dieser bei der Deklaration als Member nicht ausgenutzt werden. Komische Semantik:

    struct MyClass
    {
        int val;
    
        MyClass(int val):
            val(val) {}
    
        bool operator<( MyClass const& c ) const
        {
            return val < c.val;
        }
    };
    
    int main()
    {
        if( MyClass(7) < 4 ) // Das geht noch
            // ...
        if( 4 < MyClass(4) ) // Wums. Nicht möglich.
            // ...
    }
    


  • das heißt innerhalb der klasse würde die funktion so aussehen?

    volkard schrieb:

    ..

    Alles falsch :p



  • Mmm, sicher Sone:
    http://ideone.com/xQQE5V



  • Nathan schrieb:

    Mmm, sicher Sone:
    http://ideone.com/xQQE5V

    Es ging mir um die Definition in der Klasse http://ideone.com/hiNh2r



  • Sone schrieb:

    Nathan schrieb:

    Mmm, sicher Sone:
    http://ideone.com/xQQE5V

    Es ging mir um die Definition in der Klasse http://ideone.com/hiNh2r

    Und ging es darum, daß die Funktion in der Klasse ist.



  • Sone schrieb:

    http://ideone.com/hiNh2r

    GCC 3.9 hätte das akzeptiert.



  • volkard schrieb:

    Sone schrieb:

    Nathan schrieb:

    Mmm, sicher Sone:
    http://ideone.com/xQQE5V

    Es ging mir um die Definition in der Klasse http://ideone.com/hiNh2r

    Und ging es darum, daß die Funktion in der Klasse ist.

    Naja, ich dachte jetzt, in der Klasse heißt in der Klasse. 😋

    Übrigens, wenn du den kleiner-als Operator überlädst, solltest du auch immer direkt den ist-gleich Operator mit überladen. Die kommen meistens im Zweierpack.

    bool Element:: operator <(const Element& E) 
    { 
        Element blabla(*this); 
        return blabla.ngen < E.ngen; 
    }
    

    Wieso eine Kopie?
    Volkards dritte Lösung ist die gängigste.


Log in to reply