removeDoublesInVector()



  • Hallo,
    ich habe hier eine etwas ältere Funktion von mir, die beliebige doppelte Datentypen im vector entfernt, also Typen, wo std::sort() und std::unique() nicht klappt. zB sowas

    class C
    {
    public:
    	C(const int a, const int b, const std::string& str)
    		:a(a), b(b), str(str) {};
    
    	bool operator==(const C& c) const
    	{
    		if (a == c.a && b == c.b && str.compare(c.str) == 0)
    		{
    			return true;
    		}
    		else
    		{
    			return false;
    		}
    	}
    
    private:
    	int a = 0;
    	int b = 0;
    	std::string str;
    };
    

    Bedingung ist nur, das es dort einen operator==() gibt. Diese wollte ich hier mal "abklopfen" lassen. Ich hatte mir zwei Reihen von Münzen genommen und versucht nachzuprogrammieren, wie ich Doppelte entfernen würde. Und ich hoffe stark, das ich diesmal bei der Suche nicht gepennt habe 🙄 😉

    template<typename T> inline std::vector<T> removeDoubles(const std::vector<T>& vec)
    {
    	std::vector<T> clear_vec;
    	if (vec.empty())
    		return clear_vec;
    
    	clear_vec.push_back(vec.front());
    	bool found = false;
    
    	std::size_t c = 0;
    	while (c < vec.size())
    	{
    		for (std::size_t i = 0; i < clear_vec.size(); ++i)
    		{
    			if (vec[c] == clear_vec[i])
    			{
    				found = true;
    				break;
    			}
    			else
    			{
    				found = false;
    			}
    		}
    		if (!found)
    		{
    			clear_vec.push_back(vec[c]);
    		}
    		++c;
    	}
    	return clear_vec;
    }
    


  • @zeropage sagte in removeDoublesInVector():

    bool operator<(const C& c) const
    {
        return std::tie(a,b,str) < std::tie(c.a,c.b,c.str);
    }
    

    und schon funktionieren std::sort und std::unique.

    Und mit C++20 reicht

    auto operator<=>(const C&) const = default;
    


  • Sieht ganz gut aus. Man kann die innere Schleife noch durch ein std::find ersetzen, aber algorithmisch wirst du ohne Vergleichsoperator oder Hashcode nicht viel besser werden können.



  • Aha, danke. Und wieder was gelernt.

    Zu manni66' Antwort, hat Visual Studio 19 bei 'latest Draft' schon C++20? Ich weiß, ich könnte das jetzt einfach versuchen, aber ebenso auch fragen 😉



  • Apropos, warum ich mir überhaupt diese Funktion geschrieben habe. Ich hatte mir in einer Konsolenanwendung "selbst gemischte" Farben gemacht, also Kombinationen aus char, Vordergrund- und Hintergrundfarbe. Dort kommen bei unterschiedlichen Kombinationen auch selbe Farben raus, weshalb die Prüfung etwas umständlicher ist.

    bool Char::operator == (const Char& chr) const
    {
    	bool e = false;
    	if (wchar == chr.wchar
    		&& fg_color == chr.fg_color
    		&& bg_color == chr.bg_color)
    	{
    		e = true;
    	}
    	if (fg_color == chr.bg_color
    		&& bg_color == chr.fg_color)
    	{
    		e = true;
    	}
    	return e;
    }
    
    bool Char::operator != (const Char& chr) const
    {
    	if (wchar != chr.wchar
    		|| fg_color != chr.fg_color
    		|| bg_color != chr.bg_color)
    	{
    		return true;
    	}
    	else
    	{
    		return false;
    	}
    }
    

    std::tie() dürfte hier nicht mehr funktionieren?



  • @zeropage sagte in removeDoublesInVector():

    hat Visual Studio 19 bei 'latest Draft' schon C++20?

    Nicht alles, ich meine aber operator<=> geht schon.



  • Ok, danke.



  • Meine Antwort bezieht sich natürlich auf beliebige Typen, also wenn <=> etc. nicht vorliegen. Ansonsten ist es natürlich immer besser, z.B. Sortierbarkeit auszunutzen.



  • @zeropage: Warum hast du den operator != nicht mittels return !(*this == chr) implementiert?

    Und bei dem operator == solltest du ein else if benutzen (oder gleich return true benutzen).



  • Gute Frage, jetzt beim hier reinkopieren ist mir das auch aufgefallen. Es hatte aber seinen Grund, ist aber schon länger her, ich überprüfe das nochmal. Kann aber einen Moment dauern, bei mir ist die Heizung ausgefallen und ich zittere hier ein wenig mit leeren Magen, kann mich nicht richtig konzentrieren.

    Werde aber auf jeden Fall auf die berechtigte Frage antworten.

    EDIT. Ups, jetzt scheint die erste Frage verschwunden zu sein? Oder ich bin jetzt vollkommen kirre 😉
    Wegen *this, damit habe mich noch nie befasst, bisher habe ich um alles, was wie ein Pointer aussieht einen großen Bogen gemacht. Und bei mir ist es leider so, erst wenn ich es anwende, habe ich es verstanden. Nur lesen reicht bei mir leider nicht aus.



  • Sorry, die erste Frage war falsch, da ich zuerst nicht gesehen hatte, daß die beiden if-Abfragen unterschiedlich sind (bzgl. fg_color und bg_color).

    Und *this bedeutet einfach, daß das aktuelle Objekt zum Vergleich heran gezogen wird (da this ein Zeiger auf das aktuelle Objekt ist, muß es dereferenziert werden).



  • Alles klar, danke für die Rückmeldung 🙂
    Und this werde ich mal üben, kommt ja öfter in Codes vor.


Anmelden zum Antworten