Map

YumiFerrari

Grünschnabel
Hallo,

ich brauche dringend Hilfe und hoffe, dass mir vllt jemand helfen kann.

Ich habe eine CSV Datei, die ich einlesen. Ich hab erst mal 2 Spalten hiervon eingelesen. In der einen Spalte stehen die Namen und in der zweiten die dazugehörigen Adressen. Als Input gebe ich den gesuchten Namen ein und als Output erhalte ich die Adresse. Das klappt auch soweit. Nur es gibt es Problem und zwar, dass manchmal Namen doppelt auftauchen. Die Map überschreibt diese dann.

In der CSV Datei ist auch eine Spalte, wo die Levels der jeweiligen Namen stehen. Das würde dann die Überschreibung verhindern, Nur ich weiß nicht genau, wie ich das mit einbinden kann. Dann müsste die Eingabe sich auch so ändern, dass man den genauen Namenspfad eingeben muss. Nun zu der frage... kann man bei einer Map noch eine Schleife mit einbauen, wo man dann vorgibt, wie die Namen einzulesen sind?

z.B.

Level Name

1 A
2 B
3 C
4 D
4 E
3 D


Also wenn ich das zweite D haben möchte, dann müsste ich als Input eingeben GetAddress(1.2.3) also mit den Namen jetzt GetAdress(A.B.D).....
und wenn ich das erste D haben möchte, dann eben GetAddress(1.2.3.4) und in namen ausgeschrieben GetAddress(A.B.C.D)...

Leicht erklärt, aber ich weiß nicht, wie ich das mit bedingungen in einer Schleife festlegen kann. Weil die Namen ja auch so in die Map geladen werden müssen.


Kann mir einer helfen?
 
Also um das klar zu bekommen, wenn das ganze ausflachen würdest, hättest du eine Tabelle mit 3 Spalten, in etwa so:

| Level | Name | Adresse |

und Level + Name ergeben den Primary key welcher dann unique ist (in relationaler Sprache gesprochen :) ) - Was du jetzt haben willst ist eine Map, die den composite primary key (Level + Name) zur Adresse mappt?

Wenn das so ist würde ich vorschlagen diesen composite key als Key für die Map zu verwenden, alles andere macht nicht wirklich viel sinn - in meinen Augen.

lg Chris
 
Hallo,

danke erst mal für eure Rückmeldung,

@ Chris:
Ja du hast zum Teil recht. Das ist aber nicht Level + Name, sondern der Namepfad, der mit Hilfe der Levels erstellt wird. Diesen Namen wollte ich als Key für die Map nehmen. So wird nicht nur der Name mit der dazugehörigen Adresse in die Map geladen, sondern der Namenpfad mit der Adresse. Verstehst du was ich meine?

@ MCOder:
Das mit der Multimap habe ich mir auch schon überlegt, aber da bekomme ich alle möglichen Treffer für einen Key raus. Das ist ja nicht mein Ziel. Daher habe ich diesen Gedanken auch schon wieder fallen lassen.
 
ich hab mir jetzt was überlegt, wenn man die Map Funktion so lässt....ich hab in der Map Funktion eine Schleife. Ich wollte da noch eine Schleife mit einbauen, die dann eben die Levels überprüft...

n Level der aktuellen Zeile
j Level der nachfolgenden Zeile

j > n -> bei diesem Fall wird der Name von j an den von n drangehängt und in die Map geladen
j < n -> be diesem Fall sollen die kleinere Zahl in den gelesenen Zeilen gesucht werden und dann wird überprüft, ob die 1. Bedingung erfüllt wird. Dann alles wie bei der 1. Bedingung
j = n -> hier wird genau das gemacht wie bei Bedingung 2.

So wird der Namenpfad als Key in die Map geladen. Dann kann ich es wie ich das jetzt auch mache den Namen eingeben und bekomme dann die Adresse als Ausgabe....


Den ersten if loop hab ich jetzt hinzugefügt wegen den Levels. Der zweite war dafür da, die Namen und Adresse zu laden, was auch soweit geklappt hat.
getline(MyFile, String);

Ich habs versucht, aber durchlaufen werden immer fehler angezeigt. Ich bin auch so doof.... ich sag zwar, dass ich die Levels von der aktuellen Zeile und der davor einsetze, aber das Programm weiß die ja gar nicht. Daher müsste ich mir was einfallen lassen, wo ich in die Spalte gehe und die Werte einlese und mit denen dann arbeite.
 
Zuletzt bearbeitet:
Hallo YumiFerrari,

damit du die Keys (Pfade) richtig bauen kannst, ist es, denke ich, am einfachsten die Datei vorher schon mal komplett einlesen. Dann kannst in der Liste schnell zurückgehen und die Pfade entsprechend bauen.

Das könnte vielleicht so aussehen:
C++:
#include <iostream>
#include <map>
#include <vector>
#include <iomanip>

class DataRecord
{
    public:
        DataRecord() { }

        DataRecord(int nLevel, std::string strName, std::string strAddr)
            :
            m_nLevel(nLevel), m_strName(strName), m_strAddr(strAddr)
        {
        
        }        

        int         m_nLevel;
        std::string m_strName;
        std::string m_strAddr;
};

std::string BuildKey(int nIndex, std::vector<DataRecord>& vData)
{
    std::string strKey        = vData[nIndex].m_strName;
    int         nCurrentLevel = vData[nIndex].m_nLevel;
    
    while( nCurrentLevel > 1 && nIndex > 0 )
    {
        nIndex--;
        
        if( (vData[nIndex].m_nLevel + 1) == nCurrentLevel )
        {
            strKey = vData[nIndex].m_strName + "." + strKey;
            nCurrentLevel--;
        }
    }
    
    return strKey;
}

int main( int argc, const char* argv[] )
{
    // Testdaten    
    
    std::vector<DataRecord> vData;
    vData.push_back(DataRecord(1, "A", "Adresse A"));
    vData.push_back(DataRecord(2, "B", "Adresse B"));
    vData.push_back(DataRecord(3, "C", "Adresse C"));
    vData.push_back(DataRecord(4, "D", "Adresse D1"));
    vData.push_back(DataRecord(4, "E", "Adresse E"));
    vData.push_back(DataRecord(3, "D", "Adresse D2"));

    // Map füllen
    
    std::map<std::string,DataRecord> mapData;
        
    for( unsigned int i = 0; i < vData.size(); ++i )
    {
        std::string strKey = BuildKey(i, vData);
        
        mapData[strKey] = vData[i];
        
        std::cout << std::setw(10) << std::setfill(' ') << strKey << "   "
                  << vData[i].m_nLevel  << "   "
                  << vData[i].m_strName << "   "
                  << vData[i].m_strAddr
                  << std::endl;
    }

    return 0;
}
Gruß
MCoder
 
Danke für das Beispiel, aber ich verstehe nicht ganz wie du das meinst mit vorher schon durchlesen.Also das ist ja das was ich jetzt habe an code (also ein teil), was auch soweit funktioniert.
müsste jetzt dein beispiel davor gehängt werden?

if (String != Line) // If the line is not empty
{
Line = String;
pointer_mychar = &String[0];

pointer_mychar = strtok(pointer_mychar, delimiter);

int i=0;
int pairfind = 0;


while(pointer_mychar != NULL)
{

if (i>1 && i<4) // Reading column 2 and 3 only. (Name and Address)
{

if (pairfind == 0) {

Name = newString;// get the Namepath from the loop before
pairfind = 1;
} else (pairfind == 1) {
Address = pointer_mychar; // Address
pairfind =2;
}
pointer_mychar = strtok(NULL, delimiter);

i++;
}
 
Zuletzt bearbeitet:
das problem ist auch, dass es hier ja nur ein beispiel war. eigentlich weiß ich vorher ja nicht wie groß die csv datei ist und hm.... ich hab grad irgendwie den faden verloren.....
 
Zurück