was nimmt man am einfachsten fürs mappen?



  • Hallo zusammen,

    die Frage ist vermutlich ganz einfach, aber bei der Hitze bin ich verwirrt. Ich habe folgendes Problem: Ich muss für eine bestimmte Knotennummer einen Ausgangsport auf einen Zielport mappen. Das ganze soll statisch erfolgen. Schön wäre so was wie:

    int destPort = map(nodeID, outPort);

    Das Problem ist aber das jeder Knoten eine unterschiedliche Anzahl von Ausgängen haben kann, es sind mindestens 1 und maximal 7. Wie macht man dies?

    Ein genaues Beispiel wäre so:

    NODE_ID, OUT_PORT ---> DEST_PORT
            0 1 -->  0
            0 2 -->  1
            0 3 -->  2
            0 4 -->  3
            1 0 -->  0
            2 0 -->  0
            3 0 -->  0
            4 0 -->  0
            4 5 -->  1
            4 6 -->  2
            5 4 -->  0
            6 4 -->  0
    

    Mit mehrdimensionalen Arrays geht dies ja nicht, oder?
    Danke.



  • Am einfachsten vielleicht mit einer std::map<int,int> und

    return theMap[10*nodeID+1*outPort];
    


  • Keine Ahnung was bei dir Knoten, outPort und destPort sein soll, aber fuer die Abbildung in deinem Beispiel gibt es viele Moeglichkeiten. Vielleicht std::map mit eine Paar als Schluessel und entsprechender Vergleichsfunktion.

    Mit mehrdimensionalen Arrays geht dies ja nicht, oder?

    Warum nicht?



  • Hey,

    aber eine Map lässt doch explizit keine doppelten Schlüssel zu, welche ich ja habe, siehe die NODE_ID 0 Einträge. Oder wie meinst du dies?
    Danke.



  • uwerothfeld schrieb:

    Hey,

    aber eine Map lässt doch explizit keine doppelten Schlüssel zu, welche ich ja habe, siehe die NODE_ID 0 Einträge. Oder wie meinst du dies?
    Danke.

    Deswegen habe ich die nodeID doch vorher mit 10 plutimiziert.



  • Hey volkard,

    10 * 0 ? Wie soll das Helfen?

    Mit würde dann irgendwie sowas vorschweben:

    typedef std::pair<int, int> SOURCE_TA_DEST_TA;
            std::map<SOURCE_TA_DEST_TA, int> TA_PORT_MAP;
    
            TA_PORT_MAP.insert(std::make_pair(0,1),0);
            TA_PORT_MAP.insert(std::make_pair(0,2),1);
            TA_PORT_MAP.insert(std::make_pair(0,3),2);
            TA_PORT_MAP.insert(std::make_pair(0,4),3);
            TA_PORT_MAP.insert(std::make_pair(1,0),0);
            TA_PORT_MAP.insert(std::make_pair(2,0),0);
            TA_PORT_MAP.insert(std::make_pair(3,0),0);
            TA_PORT_MAP.insert(std::make_pair(4,0),0);
            TA_PORT_MAP.insert(std::make_pair(4,5),1);
            TA_PORT_MAP.insert(std::make_pair(4,6),2);
            TA_PORT_MAP.insert(std::make_pair(5,4),0);
            TA_PORT_MAP.insert(std::make_pair(6,4),0);
    

    Aber kann man das auch const definieren? Also das es nur in einer H Datei steht? Wohl nicht, oder?
    Danke.



  • uwerothfeld_ schrieb:

    Hey volkard,
    10 * 0 ? Wie soll das Helfen?

    Du denkst

    NODE_ID, OUT_PORT ---> DEST_PORT 
            0 1 -->  0 
            0 2 -->  1 
            0 3 -->  2 
            0 4 -->  3 
            1 0 -->  0 
            2 0 -->  0 
            3 0 -->  0 
            4 0 -->  0 
            4 5 -->  1 
            4 6 -->  2 
            5 4 -->  0 
            6 4 -->  0
    

    Und ich denke

    NODE_ID, OUT_PORT ---> DEST_PORT 
              1 -->  0 
              2 -->  1 
              3 -->  2 
              4 -->  3 
             10 -->  0 
             20 -->  0 
             30 -->  0 
             40 -->  0 
             45 -->  1 
             46 -->  2 
             54 -->  0 
             64 -->  0
    

    Und das Initialisieren kannst Du zum Beispiel wegmachen mit

    Header

    std::map<...,int>& getTA_PORT_MAP();
    

    *.cpp

    std::map<...,int> createTheTA_PORT_MAP(){
      static std::map<...,int> theTA_PORT_MAP;
      theTA_PORT_MAP[12]=4;//usw...
      return theTA_PORT_MAP;
    }
    std::map<...,int>& getTA_PORT_MAP();{
      static std::map<...,int> theTA_PORT_MAP=createTheTA_PORT_MAP();
      return theTA_PORT_MAP;
    }
    

    Und verwendet mit

    cout<< getTA_PORT_MAP()[10*node+port] <<'\n';
    
    //oder bei häufiger verwendung sich ne lokale Referenz ziehen
    
    std::map<...,int>& portMap=getTA_PORT_MAP();
    cout<< portMap[10*node+port] <<'\n';
    

    Wobei der *10-Trick nicht zwingend ist. Kannst auch std::pair nehmen oder ein zweidimensionales Array, dabei die nichtbelegten Ports auf 0 oder 8 oder wasauchimmer Ungültigkeit definiert. Oder schauen, daß 4 Bit pro Portnummer mal 8 Ports == 32 Bit und paßt noch supi in einen int32 und ein eindimensionales nehmen. Oder 8 Bit zum Nachschauen, ob Port existiert, plus 8*3 wären genau 32. Oh, das ist ja nichts anderes als wenn man 4 Bit für die Zahlen 0 bis 15 nimmt und Zahlen von 8 bis 15 sagen Ungültigkeit.



  • Hallo volkard,

    sehr schön. Verstehe. Ist die Hitze, behaupte ich mal 😉

    Eine Frage noch, warum machst du dies:

    std::map<...,int>& getTA_PORT_MAP();{
      static std::map<...,int> theTA_PORT_MAP=createTheTA_PORT_MAP();
      return theTA_PORT_MAP;
    }
    

    Also warum die lokale static Variable?

    Gruß und vielen Dank. 🙂



  • ...



  • Weil es sonst komplizierter wäre, die Variable anzulegen.
    (Sie wäre entweder global oder static in der Klasse, was aufs gleiche hinausführt)
    Auf jeden Fall müsste man Sie trotzdem noch irgendwo initialisieren und befüllen.
    Das macht die Fkt alles schon von alleine.

    bb



  • uwerothfeld schrieb:

    Also warum die lokale static Variable?
    Gruß und vielen Dank. 🙂

    Da gehts nur ums static, was dafür sorgt, daß noch schnell geprüft wird, ob die Variable schon initialisiert wurde, und die Initialisierung (hier den teuren Funktionsaufruf) nur macht, wenn das während dieses Programmlaufs noch nicht geschehen ist.
    Den Trick benutzt man gerne, wenn man sich die teure Initialisierung zu Programmstart sparen will und sie so weit nach hinten verzögertm bis sie wirklich gebraucht wird. Aber zu Kosten von einem if pro Zugriff. Dabei bin ich sonst gar kein solcher Fan von Kosten. Hier der Code, wie er zu Programmstart initialisiert und kein if drin hat.

    std::map<...,int> createTheTA_PORT_MAP(){
      static std::map<...,int> theTA_PORT_MAP;
      theTA_PORT_MAP[12]=4;//usw...
      return theTA_PORT_MAP;
    }
    static std::map<...,int> theTA_PORT_MAP=createTheTA_PORT_MAP();
    std::map<...,int>& getTA_PORT_MAP();{
      return theTA_PORT_MAP;
    }
    

    Man beachte die furchtbar unterscvhiedlichen Bedeutungen von static. Welch ein Zufall, daß die Zeile trotzdem im Ganzen verschoben werden wollte.

    Oder im header die map per extern deklarieren und einfach als globale Variable leben lassen.
    *.h

    extern static std::map<...,int> theTA_PORT_MAP;
    

    *.cpp

    std::map<...,int> createTheTA_PORT_MAP(){
      static std::map<...,int> theTA_PORT_MAP;
      theTA_PORT_MAP[12]=4;//usw...
      return theTA_PORT_MAP;
    }
    std::map<...,int> theTA_PORT_MAP=createTheTA_PORT_MAP();
    

    Dann aber nicht mehr drauf zugreifen, bevor die main() gestartet wurde.

    Oder gleich richtig machen und
    *.cpp

    static std::map<...,int> theTA_PORT_MAP...
    
    int getDestPort(int nodeID,int destPort){
       //hier schlaue Implementierung, denn der *10-Trick muß ja weg
       //und darf nicht in den Anwendungscode. 
    }
    

Anmelden zum Antworten