Maps



  • Du kannst natürlich auch Templates verwenden, sodass du es für beliebige Typen-Kombinationen verwenden kannst:

    #include <iostream>
    #include <string>
    #include <map>
    
    using namespace std;
    
    template <typename T, typename U>
    class SuperMap
    {
        private:
            map<T, U> mapT;
            map<U, T> mapU;
    
        public:
            U &operator[](const T &key)
            {
                return this->mapT[key];
            }
    
            T &operator[](U key)
            {
                return this->mapU[key];
            }
    };
    
    using namespace std;
    
    int main()
    {
        SuperMap<int, string> foo;
    
        foo["test"] = 0;
        foo[0] = "test";
    
        SuperMap<float, int> foo2;
    
        foo2[0.111f] = 1234;
        foo2[0] = 12.34f;
    
        return 0;
    }
    


  • Ah, das ist eine viel schönere Lösung, als 4 verschiedene Maps anzulegen,
    allerdings habe ich ein Problem beim anlegen einer neuen Map in der Main.

    Ich erzeuge eine mit

    MapDictionary<int, string> maptest;
    

    Dann sagt der Compiler aber, dass int und String unzulässige Typnamen sind?!



  • Allerdings findet er angeblich auch kein cin und cout.. Obwohl ich

    using namespace std;
    

    benutze..



  • Für std::cin/std::cout brauchst du den Header iostream. Für std::string brauchst du den Header string. Zeig doch mal deinen Code...



  • Mapper schrieb:

    Ups, hab das ein bisschen zu flüchtig gemacht. Merk ich z. B. daran, dass ein mal this-> fehlt und der int unnötigerweise per Referenz übergeben wird. Das Prinzip sollte aber klar sein.

    Da fehlt kein this-> (eins zuviel).
    Was der TE sucht, ist** boost::bimap **.



  • //header
    #ifndef Uebung9.3_h
    #define Uebung9.3_h
    
    #include <string>
    #include <map> 
    
    using namespace std;
    template <typname T, typname U>
    
    class MapDictionary {
    
    private:
            map<T, U> mapT;
            map<U, T> mapU;
    
    public:
            U &operator[](const T &key)
            {
                return this->mapT[key];
            }
    
            T &operator[](U key)
            {
                return this->mapU[key];
            }
    }
    
    #endif
    
    #include "Uebung9.3.h"
    
    using std::map;
    using std::cout;
    using std::string;
    using std::cin;
    using std::endl;
    //using namespace std;
    
    int main()
    {
    	MapDictionary<int, string> maptest;
    
    	maptest["eydu"] = 15487;
    	maptest[815] = "geheim";
    	maptest[10105588799] = 8234;
    	maptest["visa"] = "hallo";
    
    	string key;
    	/*cout << "Key = ";
    	cin >> key;
    
    	map <int, string>::iterator it;
    	it = maptest.find(key);
    
    	if (it != maptest.end())
    	{
    		cout << "Key: " << it->first << " Vaule: " << it->second << endl;
    	}*/
    }
    

    Hab den Rest extra auskommentiert, weil anscheinend die std::map Sachen auch nicht erkannt werden



  • Hacker schrieb:

    Mapper schrieb:

    Ups, hab das ein bisschen zu flüchtig gemacht. Merk ich z. B. daran, dass ein mal this-> fehlt und der int unnötigerweise per Referenz übergeben wird. Das Prinzip sollte aber klar sein.

    Da fehlt kein this-> (eins zuviel).

    Wo is da eins zu viel?

    Hacker schrieb:

    Was der TE sucht, ist** boost::bimap **.

    Nein, er will ja vorerst kein Boost:

    KeinNameMehrFrei schrieb:

    Mit Boost möchte ich (noch) nicht arbeiten.



  • booster schrieb:

    Nein, er will ja vorerst kein Boost:

    KeinNameMehrFrei schrieb:

    Mit Boost möchte ich (noch) nicht arbeiten.

    Glatt übersehen 😃
    this-> ist völlig unnötig, außer lokale Variablen haben den gleichen Identifier wie eine deiner Member.



  • Hacker schrieb:

    this-> ist völlig unnötig.

    Geschmackssacke.



  • feinschmecker schrieb:

    Hacker schrieb:

    this-> ist völlig unnötig.

    Geschmackssacke.

    Aber kein Muss. Deswegen ist die Aussage "da muss noch ein this-> hin" falsch.



  • Ob this oder nicht, das ist ja hier jetzt nicht das Problem 😃



  • Hacker schrieb:

    feinschmecker schrieb:

    Hacker schrieb:

    this-> ist völlig unnötig.

    Geschmackssacke.

    Aber kein Muss. Deswegen ist die Aussage "da muss noch ein this-> hin" falsch.

    Gegenteiliges hab ich auch nie behauptet. Ich hab nur gesagt, dass da ein "this->" fehlt, was ich auf meinen Beitrag bezogen hab, weil ich es ein mal hin geschrieben und beim anderen aus Versehen vergessen hab.



  • Gut gut, schon verstanden. Zurück zum Thema - oder besser gesagt zu seinem Code.



  • Schön 😃
    Der, falls es nicht bemerkt wurde, bereits gepostet wurde 😉



  • Jo, du inkludierst natürlich nicht <iostream> .
    Vergiss übrigens nicht, dass beide Maps in MapDictionary unabhängig von einander existieren.



  • Ja, hatte es mit Map schon bemerkt..

    Danke, natürlich war es (mal wieder) iostream. 🙄



  • KeinNameMehrFrei schrieb:

    Brauch es auch nur für int und String.

    Ich hab 4 Fälle:
    <int, string>
    <string, int>
    <string, string>
    <int, int>

    Jetzt würde mich dochmal die Aufgabenstellung interessieren.



  • Theoretisch würde ich sowas nehmen:

    template<typename key1T, typename key2T>
    struct bimap
    {
            typedef std::vector<std::pair<key1T, key2T>> array_type;
            array_type array;
    
            typename array_type::iterator find(key2T tof)
            {
                    typename array_type::iterator iter = array.begin();
                    for(;iter != array.end();++iter)
                            if(iter->second == tof)
                                    break;
    
                    return iter;
            }
    
            typename array_type::iterator find(key1T tof)
            {
                    typename array_type::iterator iter = array.begin();
                    for(;iter != array.end();++iter)
                            if(iter->first == tof)
                                    break;
    
                    return iter;
            }
    
            key1T& operator[](key2T a)
            {
                    typename array_type::iterator iter;
                    if((iter = find(a)) != array.end())
                            return iter->first;
    
                    array.push_back(std::make_pair(key1T(), a));
                    return array.back().first;
            }
            key2T& operator[](key1T a)
            {
                    typename array_type::iterator iter;
                    if((iter = find(a)) != array.end())
                            return iter->second;
    
                    array.push_back(std::make_pair(a, key2T()));
                    return array.back().second;
            }
    };
    

    Nur ist halt das Problem, dass es nicht reguläre Memberfunktionen wie in einer std::map gibt... ⚠
    ➡ 💡
    Aufgabe für heute gefunden!



  • .. und das es ziemlich langsamer pfusch ist.. 😉



  • daki schrieb:

    .. und das es ziemlich langsamer pfusch ist.. 😉

    Na wenn du das gleich so sagst... machs besser ( :Herausforderung: ) 🤡

    Ich bin soweit fertig (unimplementierte Funktionen sind ja durch das Set verfügbar, und da das nur ein Wrapper um ein Set ist...).

    template<typename leftKeyT, typename rightKeyT>
    class bimap
    {
    public:
    
            typedef std::pair<leftKeyT, rightKeyT> value_type;
            typedef std::set<value_type> array_type;
    
            array_type mSet;///Internal array (set)
    
            typedef leftKeyT left_key_type;
            typedef rightKeyT right_key_type;
    
            typedef typename array_type::iterator iterator;
            typedef typename array_type::const_iterator const_iterator;
            typedef typename array_type::size_type size_type; //Hier können theoretisch noch andere typedefs hin, aber die sind durch das Set verfügbar
    
            iterator find(rightKeyT const& tof)
            {
                    return find(tof);
            }
    
            iterator find(leftKeyT const& tof)
            {
                    return find(tof);
            }
    
            const_iterator find(rightKeyT const& tof) const
            {
                    return std::find_if(mSet.begin(), mSet.end(), [&](value_type const& a){return a.second == tof;});
            }
    
            const_iterator find(leftKeyT const& tof) const
            {
                    return std::find_if(mSet.begin(), mSet.end(), [&](value_type const& a){return a.first == tof;});
            }
    
            leftKeyT& operator[](rightKeyT const& a)
            {
                    return const_cast<leftKeyT&>(insert(a).first->first);
            }
    
            rightKeyT& operator[](leftKeyT const& a)
            {
                    return const_cast<rightKeyT&>(insert(a).first->second);
            }
    
            void clear()
            {
                    mSet.clear();
            }
    
            size_type count(leftKeyT const& lK) const
            {
                    return std::count_if(mSet.mSet.begin(), mSet.end(), [&](std::pair<leftKeyT, rightKeyT> const& p)
                                                                       {
                                                                            return p.first == lK;
                                                                       });
            }
            size_type count(rightKeyT const& rK) const
            {
                    return std::count_if(mSet.mSet.begin(), mSet.end(), [&](std::pair<leftKeyT, rightKeyT> const& p)
                                                                       {
                                                                            return p.second == rK;
                                                                       });
            }
    
            size_type erase(rightkeyT const& lK)
            {
                    size_type rval = count(lK);
                    std::remove_if(mSet.begin(), mSet.end(), [&](value_type const& p){return p.second == lK;});
                    return rval;
            }
    
            size_type erase(leftkeyT const& lK)
            {
                    size_type rval = count(lK);
                    std::remove_if(mSet.begin(), mSet.end(), [&](value_type const& p){return p.first == lK;});
                    return rval;
            }
    
            template<typename keyT>
            std::pair<iterator, bool> insert(keyT const& t)
            {
                    std::pair<iterator, bool> rval(find(t), false);
    
                    if(rval.first != mSet.end())
                            return rval;
    
                    return mSet.insert(std::make_pair(leftKeyT(), t));;
            }
    };
    

Anmelden zum Antworten