Frage zum STL Algorithmus find_if



  • Hallo STL Nutzer,

    bitte unterstützt mich bei der Anwendung des find_if STL Algorithmus.

    ich habe einen Vector für eine Klasse mit 4 String Attributen definiert und möchte eines
    dieser Attribute suchen und die drei anderen ausgeben.

    class HARNESS
    {
    public: ...

    private:

    string msn;
    string type;
    string fsn;
    string mark;

    };

    Definition der Vector Klasse:

    template<class T>
    void ShowVector(const vector<T>& v)
    {

    for (int i = 0; i < v.size(); ++i)
    cout << v[i] << "\n";
    cout << endl;
    }

    Hierfür habe ich eine Predicate Klasse wie folgt deklariert:

    class HARNESS_eq : public unary_function<HARNESS,bool>
    {
    string s;
    public:
    explicit HARNESS_eq(const string& ss): s(ss) {}
    bool operator() (const HARNESS& c) const
    { return c.fsn==s; }
    };

    Ich möchte nach der Eigenschaft fsn suchen und msn,type ausgeben.

    Definition des Algorithmus find_if :

    template<class InIt, class UnPred>
    void f(vector<HARNESS>& vh)
    {
    typedef vector<HARNESS>::iterator it1;
    it1 p = find_if(vh.begin(),vh.end(), HARNESS_eq("201"));
    if ( p != vh.end())
    {
    cout << "msn " << vh[p] << " found." << endl;
    cout << "type " << vh[p] << " found." << endl;
    }
    }

    Implementiert wie folgt:

    HARNESS A("578","A319-112","201","SET1");
    HARNESS B("533","A320-214","226","SET1");
    HARNESS C("517","A321-111","276","SET1");

    vector<HARNESS> lfz(3);
    vector<HARNESS>::iterator harness_iter;
    lfz[0]= A;
    lfz[1]= B;
    lfz[2]= C;

    typedef vector<HARNESS>::iterator it1;

    it1 p = find_if(lfz.begin(),lfz.end(), HARNESS_eq("201"));
    if (p != lfz.end())
    {
    cout << lfz[p] << " found." << endl;
    //cout << "type " << lfz[p] << " found." << endl;
    }
    else
    {
    cout << " nothing found" << endl;
    }

    Der Algorithmus arbeitet nicht !!

    Was mache ich falsch ?

    Euer ElectricProg



  • Der Algo funktioniert.
    Ich hab mal aus Deinen Brocken ein lauffähiges Beispel gebaut:

    #include <iostream>
    #include <algorithm>
    #include <functional>
    #include <string>
    #include <vector>
    using namespace std;
    
    struct HARNESS 
    { 
    	HARNESS(const std::string & a,const std::string & b,const std::string & c,const std::string & d)
    	{
    		msn = a;
    		fsn = c; 
    		type = b; 
    		mark = d; 		
    	}
    
    	string fsn; 
    	string msn; 
    	string type; 
    	string mark; 
    
    }; 
    
    class HARNESS_eq : public unary_function<HARNESS,bool> 
    { 
    	string s; 
    public: 
    	explicit HARNESS_eq(const string& ss): s(ss) {} 
    	bool operator() (const HARNESS& c) const 
    	{ return c.fsn==s; } 
    }; 
    
    int main()
    {
    
    HARNESS A("578","A319-112","201","SET1"); 
    HARNESS B("533","A320-214","226","SET1"); 
    HARNESS C("517","A321-111","276","SET1"); 
    
    vector<HARNESS> lfz; 
    vector<HARNESS>::iterator harness_iter; 
    lfz.push_back(A);
    lfz.push_back(B);
    lfz.push_back(C);
    
    typedef vector<HARNESS>::iterator it1; 
    
    it1 p = find_if(lfz.begin(),lfz.end(), HARNESS_eq("201")); 
    if (p != lfz.end()) 
    { 
    	cout<<"gefunden";
    	//cout << lfz[p] << " found." << endl; 
    	//cout << "type " << lfz[p] << " found." << endl; 
    } 
    else 
    { 
    	cout << " nothing found" << endl; 
    } 
    
    }
    

    Du wirst sehen, es wird gefunden. Benutze mal Codetags und poste mal den gesammten Code bzw. der Fehler liegt irgendwo anderst.



  • Hallo Knuddelbaer,

    ich habe Deine Änderungen eingefügt und tritzdem noch kein Resultat erhalten.

    Jedoch habe ich zu Deiner Loesung folgende Fragen:

    1. Du hast aus der Klasse HARNESS die Struktur HARNESS gemacht; Ist dies notwendig für die Nutzung des find_if Algorithmus ? Ich möchte die Klasse HARNESS als Basisklasse definieren. Gibt es dann eine andere Lösung ?

    2. Wie kann die Ausgabe vom Feld msn und type gestaltet werden ?

    Ich poste mal für ein besseres Verständnis die Dateien harness.h und harness.cpp.

    Ach ja, was sind Codetags ?
    Vielen Dank und einen guten Rutsch

    ElectricProg

    Listing harness.h

    #include <string>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;

    class HARNESS
    {
    public:
    HARNESS();
    HARNESS(const string& my_msn, const string my_type, const string my_fsn, const string my_mark);
    HARNESS(const HARNESS& rhs);
    ~HARNESS();

    string get_msn() const ;
    string get_type() const ;
    string get_fsn() const ;
    string get_mark() const ;

    void set_msn(const string& my_msn) ;
    void set_type(const string my_type) ;
    void set_fsn(const string my_fsn) ;
    void set_mark(const string my_mark) ;

    HARNESS& operator=(const HARNESS& rhs);

    //private:
    string msn;
    string type;
    string fsn;
    string mark;

    };

    class HARNESS_eq : public unary_function<HARNESS,bool>
    {
    string s;
    public:
    explicit HARNESS_eq(const string& ss): s(ss) {}
    bool operator() (const HARNESS& c) const
    { return c.fsn==s; }
    };

    Listing harness.cpp

    #include "HARNESS.h"
    ///////////////////////////////////////////////////////////
    // HARNESS.cpp
    // Implementation of the Class HARNESS
    // Created on: 29-Dez-2003 09:01:15
    ///////////////////////////////////////////////////////////

    // Initialisierung der Elementvariablen
    // Standard Konstruktor
    HARNESS::HARNESS()
    : msn(" "),type(" "),fsn(" "),mark(" ")
    { }

    // Kopier Konstruktor
    HARNESS::HARNESS(const string& my_msn, const string my_type, const string my_fsn, const string my_mark)
    : msn(my_msn), type(my_type), fsn(my_fsn), mark(my_mark)
    { }

    // Überladener Zuweisungsoperator
    HARNESS::HARNESS(const HARNESS& rhs)
    : msn(rhs.get_msn()),type(rhs.get_type()),fsn(rhs.get_fsn()),mark(rhs.get_mark())
    { }

    HARNESS::~HARNESS(){ }

    void HARNESS::set_msn(const string& my_msn)
    {
    msn = my_msn;
    }
    void HARNESS::set_type(const string my_type)
    {
    type = my_type;
    }
    void HARNESS::set_fsn(const string my_fsn)
    {
    fsn = my_fsn;
    }
    void HARNESS::set_mark(const string my_mark)
    {
    mark = my_mark;
    }
    string HARNESS::get_msn() const
    {
    return msn;
    }
    string HARNESS::get_type() const
    {
    return type;
    }
    string HARNESS::get_fsn() const
    {
    return fsn;
    }
    string HARNESS::get_mark() const
    {
    return mark;
    }

    HARNESS& HARNESS::operator=(const HARNESS& rhs )
    {
    msn = rhs.get_msn();
    type = rhs.get_type();
    fsn = rhs.get_fsn();
    mark = rhs.get_mark();
    return *this;
    }

    ostream& operator<<(ostream& os, const HARNESS& rhs)
    {
    os << rhs.get_msn() << " " << rhs.get_type() << " " << rhs.get_fsn() << " " << rhs.get_mark();
    return os;
    }

    template<class T>
    void ShowVector(const vector<T>& v)
    {
    //cout << "max_size() = " << v.max_size();
    //cout << "\tsize() = " << v.size();
    //cout << "\tcapacity() = " << v.capacity();
    //cout << "\t" << (v.empty()? "leer": "nicht leer");
    //cout << "\n";

    for (int i = 0; i < v.size(); ++i)
    cout << v[i] << "\n";
    cout << endl;
    }

    template<class InIt, class UnPred>
    void f(vector<HARNESS>& vh)
    {
    typedef vector<HARNESS>::iterator it1;
    it1 p = find_if(vh.begin(),vh.end(), HARNESS_eq("201"));
    if ( p != vh.end())
    {
    //cout << "msn " << v[p] << " found." << endl;
    //cout << "type " << v[p] << " found." << endl;
    }
    }

    int main()
    {
    HARNESS A("578","A319-112","201","SET1");
    HARNESS B("533","A320-214","226","SET1");
    HARNESS C("517","A321-111","276","SET1");

    vector<HARNESS> lfz(3);
    vector<HARNESS>::iterator harness_iter;
    lfz[0]= A;
    lfz[1]= B;
    lfz[2]= C;
    //ShowVector(lfz);

    typedef vector<HARNESS>::iterator it1;

    it1 p = find_if(lfz.begin(),lfz.end(), HARNESS_eq("201"));
    if (p != lfz.end())
    {
    cout << lfz[p] << " found." << endl;
    //cout << "type " << lfz[p] << " found." << endl;
    }
    else
    {
    cout << " nothing found" << endl;
    }
    system("pause");
    return 0;
    }



  • Wenn ich mich nicht irre, musst du nur die folgende Zeile ändern (das hat Knuddlbaer allerdings auch schon in seinem Codebeispiel gemacht):

    cout << lfz[p] << " found." << endl;
    

    p ist hier ein iterator, das heißt du kannst ihn nicht als Index für den Vektor benutzen, es muss so aussehen:

    cout << (*p).get_msn();
    

    Den Button Codetags findest du übrigens über absenden, nennt sich dort : C/C++, er dient zur besseren Lesbarkeit deines Codes!



  • Hallo KPC,

    mit Deiner Änderung funktioniert alles wie gewünscht.

    Vielen Dank und guten Rutsch !!

    Dein ElectricProg



  • electricProg schrieb:

    Hallo Knuddelbaer,

    1. Du hast aus der Klasse HARNESS die Struktur HARNESS gemacht; Ist dies notwendig für die Nutzung des find_if Algorithmus ? Ich möchte die Klasse HARNESS als Basisklasse definieren. Gibt es dann eine andere Lösung ?

    Ich hab versucht aus den Fragmenten schnell einen Code zu bekommen den man einem Compiler geben kann.
    struct weil ich (unsauber) alles public haben wollte. Hatte keine Lust set und get zu implementieren.

    Auf die Ausgabe ist KPC eingegangen. (ich würde aber nicht (*p).get... schreiben sondern p->get...)

    Ansonsten schau Dir Deinen Source mal in ruhe an.

    Der Konstruktor ist als Beispiel noch auffällig.

    Und nutz bitte CodeTags


Anmelden zum Antworten