Vector: min_element eines Vector mit Objekten


  • Mod

    Die (int) DKNummer ist nunmehr eine public in der Klasse "Auftragnehmerkopie".

    Richtig. Und weil es ein (nicht-statischer) Member ist, kannst du auch nur über ein existierendes Objekt darauf zugreifen. Geht dir ein Licht auf?



  • Klotz schrieb:

    begin() soll meines Erachtens Teil des Befehls distance (...) sein.

    Und warum ist es dann bei dir Bestandteil von int? a.b() hat eine konkrete Bedeutung. Welche?

    Zeige wie du die DKNummer aller Elemente aus Auftragnehmerkopie unter Verwendung von Iteratoren ausgeben würdest.



  • Klotz schrieb:

    int Position;
                    Position=std::distance(Auftragnehmerkopie.DKNummer.begin(),std::min_element(Auftragnehmerkopie.DKNummer.begin(), Auftragnehmerkopie.DKNummer.end()));
    

    Auftragnehmerkopie ist deine Klasse, kein vector welcher begin() zur Verfuegung stellt. Wo also soll deine Klasse ploetzlich begin() herzaubern?!

    Hier ist einfach mal der beispielcode aus den docs zu std::distance , da du die docs offensichtlich nicht gelesen hast.

    #include <iostream>
    #include <iterator>
    #include <vector>
    
    int main() 
    {
        std::vector<int> v{ 3, 1, 4 };
        std::cout << "distance(first, last) = "
                  << std::distance(v.begin(), v.end()) << '\n'
                  << "distance(last, first) = "
                  << std::distance(v.end(), v.begin()) << '\n';
    }
    


  • Cardiac schrieb:

    Auftragnehmerkopie ist deine Klasse, kein vector welcher begin() zur Verfuegung stellt.

    Auftragnehmerkopie ist schon ein Vector...

    vector<AN> Auftragnehmerkopie(Auftragnehmer); // in WM_PAINT
    

    Aber DKNummer ist kein Vector...



  • Hallo,

    danke erstmal für Eure Kritik.

    Ich versuche, im einzelnen darauf einzugehen.

    @Arcoth:
    Das ist richtig und eines der Probleme, über deren Lösung ich mir noch nicht klar bin. Die Variable (vector.Klasse.Variable) werden an anderer Stelle erst gefüllt. Das bedeutet, dass es möglich sein kann, dass WM_PAINT aufgerufen wird, ohne dass die Variable vorhanden ist. Dazu habe ich im Vorfeld eine Überprüfung des Vectors auf Inhalt gestellt.

    if (!Auftragnehmerkopie.empty())
                {
                    int Position;
                    Position=std::distance(std::vector<AN> Auftragnehmerkopie.DKNummer.begin(),std::min_element(std::vector<AN> Auftragnehmerkopie.DKNummer.begin(), std::vector<AN> Auftragnehmerkopie.DKNummer.end()));
    //...
    }
    

    Ob das so funktionieren kann, weiß ich nicht. Gibt es eine andere Lösung? Leider bin ich noch nicht so firm in diesen Dingen.

    @Manni66:
    Ich dachte, "Auftragnehmerkopie" ist die Instanz des Vector...

    Ausgabe per Iterator:

    std::vector<AN> Auftragnehmerkopie;
    std::vector<AN>::const_iterator its;
    //Werte füllen
    for (its=Auftragnehmerkopie.begin();its!=Auftragnehmerkopie.end();its++)
    { cout<<(*its)<<endl;
    }
    

    O.K. Ich sehe glaube ich den ersten Fehler. Ich kann distance() nicht direkt mit einer (int) abrufen, da es einen Zeiger zurück gibt?

    @Cardiac:
    Wie müsste ich dann aufrufen? So?

    Position=*std::distance(AN.DKNummer.begin(),std::min_element(AN.DKNummer.begin(), AN.DKNummer.end()));
    

    Das kann aber so nicht sein? Da ich ja zwei Klassen erzeugt habe, deren member DKNummer ist?



  • Klotz schrieb:

    @Manni66:
    Ich dachte, "Auftragnehmerkopie" ist die Instanz des Vector...

    Ja, ist es auch.

    Klotz schrieb:

    Ausgabe per Iterator:

    std::vector<AN> Auftragnehmerkopie;
    std::vector<AN>::const_iterator its;
    //Werte füllen
    for (its=Auftragnehmerkopie.begin();its!=Auftragnehmerkopie.end();its++)
    { cout<<(*its)<<endl;
    }
    

    Im Prinzip ja, aber das gibt nicht nur die DKNummer aus.
    begin() ist also ein Member des Vectors und leifert einen Iterator!

    Klotz schrieb:

    O.K. Ich sehe glaube ich den ersten Fehler. Ich kann distance() nicht direkt mit einer (int) abrufen, da es einen Zeiger zurück gibt?

    std::distannce wird mit Itaratoren aufgerufen.
    std::min_element wird auch mit Iteratoren aufgerufen und liefert einen Iterator zurück. Da du nicht zwei AN-Objekte vergleichen willst sondern jeweils nur eine Element dieser Objekte brauchst du eine Vergleichsfunktion.

    Das Ganze baust du am Besten erst mal Schritt für Schritt auf, beginnend mit min_element.



  • Was du brauchst ist die Funktion mit 3 Parametern: min_element

    template< class ForwardIt, class Compare >
    ForwardIt min_element( ForwardIt first, ForwardIt last, Compare comp );



  • temi schrieb:

    Auftragnehmerkopie ist schon ein Vector...

    Hoppla, das habe ich hart ueberlesen. Mein Fehler!



  • Hi,

    bevor ich damit starte, Eure Weisungen durchzugehen, habe ich ein Problem. Der compiler meldet mir ständig, dass die Variable DKNummer kein Bestandteil des Vector ist.

    Generell habe ich die Klasse über den STandartkonstruktor erzeugt und dann einen Vector gebildet. Ich habe aber den Eindruck, dass da irgendwas noch nicht richtig ist. Generell ist das noch so ein Schwachpunkt bei mir.

    Ablauf ist bisher:

    AN AN_Element;
    
    vector<AN> Auftragnehmer;
    // beide global
    
    // dann in der WM_PAINT
     vector<AN> Auftragnehmerkopie(Auftragnehmer);
    
    //folgend die AN.hpp
    #ifndef AN_HPP_INCLUDED
    #define AN_HPP_INCLUDED
    
    #include <iostream>
    #include <string>
    #include <vector>
    #include <windows.h>
    #include <commctrl.h>
    #include "Nachtrag.hpp"
    #include "Rechnung.hpp"
    #include "KKE.hpp"
    
    using namespace std;
    
    class AN:public KKE
    {
    public:
        int KKENummer;
        int KABNummer;
        int DKNummer;
        int Auftragsnummer;
        AN();
        ~AN();
    // es folgen einige public Funktionen und private Dateien
    }
    


  • Klotz schrieb:

    bevor ich damit starte, Eure Weisungen durchzugehen, habe ich ein Problem. Der compiler meldet mir ständig, dass die Variable DKNummer kein Bestandteil des Vector ist.

    Und damit liegt er natürlich vollkommen richtig.



  • Klotz schrieb:

    Hi,

    bevor ich damit starte, Eure Weisungen durchzugehen, habe ich ein Problem. Der compiler meldet mir ständig, dass die Variable DKNummer kein Bestandteil des Vector ist.

    DKNummer ist ein Bestandteil von AN und in deinem Vector speicherst du Objekte vom Typ AN.

    Und bevor das Nächste was du probierst auch nicht funktioniert: AN ist auch kein Bestandteil des Vectors. Lies dir einfach mal durch, wie du auf die im Vector gespeicherten Daten zugreifen kannst.

    Edit: z.B. hier: http://www.cplusplus.com/reference/vector/vector/ unter Element access



  • Klotz schrieb:

    Der compiler meldet mir ständig, dass die Variable DKNummer kein Bestandteil des Vector ist.

    Du scheinst dir das so vorzustellen, dass der vector<AN> einen "Untervektor" vector<int> DKNummer enthält, der wiederum die DKNummer-Member deiner ANs enthält.

    Das ist aber nicht der Fall.



  • Hallo,

    habe jetzt endlich Zeit, weiter zu machen. Leider weiß ich nicht, wie ich die Iteratorfunktion schreiben soll.

    for ( vector<AN>::iterator it = Auftragnehmerkopie.begin(); it !=Auftragnehmerkopie.end();)
               {
    
                   DKmin=*min_element(it->DKNummer.begin(),it->DKNummer.end());
    
                 /*  if
                   {
    
                   }
    */
                 else
               {
                   ++it;
               }
               }
    

    Dachte, dass es so jetzt stimmen müsste, aber der compiler meldet:
    "error: request for member 'begin' in 'it.gnu_cxx:_normal_iterator<...which is of non-class type int"

    Das sagt mir nicht viel. Ist jetzt DKmin falsch (int), oder der it->... code- Teil?



  • Ach Mist, ich komme nicht weiter 😕



  • Hallo,

    DKNummer ist ein 'int' und hat keine begin oder end-Funktion!
    Nur ein vector stellt diese bereit.

    Wie ich schon schrieb, benötigst du die Funktion mit der Vergleichsfunktion als Parameter:

    min_element(Auftragnehmerkopie.begin(), Auftragnehmerkopie.end(), cmp_by_DKNummer);
    

    Und nun noch die Vergleichsfunktion 'cmp_by_DKNummer' entsprechend implementieren...



  • In der Doku findest du ein Beispiel:

    http://www.cplusplus.com/reference/algorithm/min_element/



  • Hallo,

    Mensch. Danke schon mal. Ich glaube, ich habe es jetzt. Ich schreibe mal die Funktion fertig und poste dann das Ergebnis. Ich stand echt auf dem Schlauch. Vielen Dank.

    Mir war nicht klar, dass min_element drei Parameter braucht.

    Grüße,
    Chris



  • Es gibt auch die Variante mit nur zwei Parametern, aber dann vergleicht diese Funktion anhand des Operator < (der aber für deine Klasse AN bisher wohl nicht definiert ist) - aber das steht auch alles in den geposteten Links zur Doku. 😉



  • Hallo,

    ich poste mal einen Zwischenstand und würde mich über Rückmeldung freuen, weil ich eine Fehlermeldung bekomme, die ich noch nicht zuordnen kann.

    In WinMain:

    if (!Auftragnehmerkopie.empty())
                {
                for ( vector<AN>::iterator it = Auftragnehmerkopie.begin(); it !=Auftragnehmerkopie.end();)
                {
                if (it != Auftragnehmerkopie.end()&&ANGroesse>1)
                {
                DKpos=std::min_element(it->DKNummer, it->DKNummer+ANGroesse,PruefeVektorausgabe); //*
    
                DKmin=Auftragnehmerkopie[DKpos].DKNummer;
    
    bool PruefeVektorausgabe(const AN& x, const AN& y)
    {
        return x.DKNummer<y.DKNummer;
    }
    

    Der compiler meldet mir für die Zeile // *
    "invalid type argument of unary '*' (have 'int')

    Ich ahne, dass das was mit dem dritten Parameter von min_element zu tun hat.

    Generell habe ich versucht, über zwei Instanzen von <AN> die DKNummer zu vergleichen. Das scheint aber nicht zu funktionieren. Vielleicht, weil da ein Zeiger in die Funktion mitgegeben wird und kein (int)? Und die Funktion ist eine (bool)? Ist das so überhaupt richtig? Müsste nicht eine (int) erfolgen?

    Kann mir das jemand erklären? Das wäre sehr nett.



  • Th69 schrieb:

    min_element(Auftragnehmerkopie.begin(), Auftragnehmerkopie.end(), cmp_by_DKNummer);
    

    Th69 hat doch schon geschrieben, wie dein Code aussehen müsste. Hast du dir die Doku zu min_element durchgelesen? Wo steht da, dass man das mit "int" aufrufen kann? it->DKNummer ist ein int

    Die ganze Schleife kannst du dir schenken, das erledigt min_element für dich, wenn du die passenden iteratoren übergibst.


Anmelden zum Antworten