2012-10-05 20 views
6

Mam mapę z struct jako typ wartościjak dostać pasujący klucz przy użyciu wartości w mapie C++

map<int id, struct_t*> table 

struct_t 
{ 
int prev; 
int wt; 
string name; 
} 

używając tylko poprzednie, muszę znaleźć odpowiedni identyfikator. Dziękuję bardzo z góry!

EDIT:

int key=0; 
for(auto it = table.begin(); it != table.end(); ++it) 
{ 
    if(table[(*it).first].prev == ?) 
} 

ten sposób moje dane map wygląda następująco:

id prev abundance thing 
1573 -1  0  book 
1864 1573 39  beds 
2075 1864 41  tray 
1760 2075 46  cups 

dla każdego identyfikatora, muszę znaleźć następny pasujący identyfikator. Tak więc, dla 1573 z poprzedniej kolumny, muszę znaleźć pasujący "identyfikator", który jest 1864. Również std :: next nie działa, ponieważ zestaw danych może mieć pasujące identyfikatory niekoniecznie w następnym elemencie.Miej nadzieję, że to pomaga !

PROSIMY O POMOC! Mój szef jest już rozczarowany, że biorę tak dużo czasu na naukę C++

+0

Jaki jest klucz "mapy"? – hmjd

+0

masz na myśli typ danych? to int id – snazziii

+3

Mapy mają być wyszukiwane na ich klucze, a nie wartości. Może powinieneś zmodyfikować swój projekt lub użyć innego rodzaju pojemnika. – arnoo

Odpowiedz

5

Jeśli masz nowoczesny kompilator (obsługuje lambdy), można wykonać następujące czynności:

const int prevToFind = 10; 
auto findResult = std::find_if(std::begin(table), std::end(table), [&](const std::pair<int, struct_t*> &pair) 
{ 
    return pair.second->prev == prevToFind; 
}); 

int foundKey = 0; // You might want to initialise this to a value you know is invalid in your map 
struct_t *foundValue = nullptr 
if (findResult != std::end(table)) 
{ 
    foundKey = findResult->first; 
    foundValue = findResult->second; 

    // Now do something with the key or value! 
} 

Daj mi znać, jeśli masz starszego kompilatora, i mogę zaktualizować przykład, aby zamiast tego używać klasy predykatów.

+0

Używam Xcode, więc mam kompilator Apple LLVM 4.1 – snazziii

+0

Naprawdę nie rozumiem tego .. Nie potrzebuję struct, potrzebuję klucza, który jest int. – snazziii

+0

Chcesz klucz? Wygląda na to, że twoja mapa jest cofnięta ... To łatwa zmiana powyższego kodu (wystarczy użyć findResult-> pierwszy). –

3

Prosta pętla może to zrobić (jego już 3 tygodnie już!):

#include <map> 
#include <string> 
#include <iostream> 

int main() 
{ 
    std::map<int, std::string> m = { 
     std::make_pair(0, "zero"), std::make_pair(1, "one"), std::make_pair(2, "two") 
    }; 

    int key = 0; 
    for (auto &i : m) { 
     if (i.second == "two") { 
     key = i.first; 
     break; // to stop searching 
     } 
    } 

    std::cout << key << std::endl; 
} 

Oczywiście trzeba założyć własną instrukcja-if do wyszukiwania. Uwaga zwiększyć dwukierunkową mapa może być rozwiązanie (boost::bimap)

+0

Dodałem więc kierunek, w którym zmierzam, ale nie wiem, co powinienem porównywać w instrukcji if! – snazziii

+0

spróbuj 'if (i.second-> prev == the_id_youre_looking_for)' – Hendrik

+0

Wygląda to o wiele łatwiej niż akceptowana odpowiedź. Nie rozumiem, dlaczego nie miał żadnych głosów wstępnych ... –

3

pętli nad mapą oczywiście załatwia sprawę, ale może warto rozważyć użycie drugą mapę jako wskaźnik:

map<int,int> table_idx; 

przy dodawaniu nowych wpisów do table będzie trzeba aktualizować table_idx także , przechowując id, który odpowiada każdemu prev. table_idx następnie pozwalają na odwrotnej odnośnika id w log (N) Czas:

int prev_for_id = table_idx[id]; 
+0

co masz na myśli przez zapętlenie się nad mapą? – snazziii

+0

Miałem na myśli podejście przyjęte w niektórych z powyższych odpowiedzi: powtarzanie każdego wpisu na mapie do momentu znalezienia wartości, której pole 'prev' jest równe poszukiwanemu identyfikatorowi. – Hendrik

1

Im się wrażenie, że jesteś początkujący więc byłoby miło, gdyby pan powiedzieć nam, co starasz się zrobić ponieważ może próbujesz rozwiązać niewłaściwy problem.
Tak jak wspomniane mapy są przeznaczone do wyszukiwania za pomocą klucza, a nie wartości.
To powiedziawszy, jeśli nalegasz na przeszukiwanie mapy w ten sposób, prawdopodobnie będziesz chciał sprawdzić: Wzmocnij Bimap.

+0

Tak, jestem początkujący. Od 3 tygodni zmagam się z tym projektem! Zaktualizuję pytanie – snazziii

+0

ok, myślę, że rozumiem twój problem. Ze szczytu mojej głowy najpierw umieściłbym wszystkie dane na mapie (z dodanym polem, które jest początkowo zunifikalizowane). Potem przejrzałbym całą mapę i dla każdego klucza, który ma value.prev == Y zrobić mapę [Y] -> value.next = X – NoSenseEtAl

+0

To nie działa ... co to jest X i Y? – snazziii

Powiązane problemy