2011-01-05 17 views
31

Czy istnieje lista funkcji find(), ponieważ była w wektorze?Jak wyszukać element na liście STL?

Czy można to zrobić na liście?

+2

'std: : vector' ma metodę 'find()'? To dla mnie nowość. –

+0

mybad ... miałem na myśli fint (vectoriterator.begin(), vectoriterator.end(), string) –

+2

Masz rację, 'std :: vector' nie posiada metody' find() '. – Raedwald

Odpowiedz

80

Używasz std::find z <algorithm>, który działa równie dobrze dla std::list i std::vector. std::vector nie ma własnej funkcji wyszukiwania/wyszukiwania.

#include <list> 
#include <algorithm> 

int main() 
{ 
    std::list<int> ilist; 
    ilist.push_back(1); 
    ilist.push_back(2); 
    ilist.push_back(3); 

    std::list<int>::iterator findIter = std::find(ilist.begin(), ilist.end(), 1); 
} 

Zauważ, że to działa na wbudowanych typów, takich jak int jak również standardowych typów bibliotek takich jak std::string domyślnie, ponieważ mają operator== przewidziane dla nich. Jeśli używasz korzystając std::find na pojemniku typu zdefiniowanego przez użytkownika, należy przeciążać operator== aby umożliwić std::find działał prawidłowo: EqualityComparable concept

+0

Jaka jest złożoność 'std :: find()'? Być może, O (n)? –

+2

Brak możliwości binarnego wyszukiwania sortowanego kontenera? Leniwa implementacja. – LDS

+3

@LDS - 'std :: binary_search' zapewnia wyszukiwania binarne. – birryree

16

Nie, nie bezpośrednio w samej szablon std :: list. Możesz jednak użyć algorytmu std :: find:

std::list<int> my_list; 
//... 
int some_value = 12; 
std::list<int>::iterator iter = std::find (my_list.begin(), my_list.end(), some_value); 
// now variable iter either represents valid iterator pointing to the found element, 
// or it will be equal to my_list.end() 
3

Co możesz zrobić i co powinieneś zrobić, to różne sprawy.

Jeśli lista jest bardzo krótka, lub masz zamiar zadzwonić tylko raz, użyj metody liniowej powyżej.

Jednak wyszukiwanie liniowe jest jednym z największych złych rzeczy, które znalazłem w powolnym kodzie, i rozważ użycie sortowanej kolekcji (set lub multiset, jeśli zezwalasz na duplikaty). Jeśli chcesz zachować listę z innych powodów, np. Używając techniki LRU lub potrzebujesz zachować zamówienie reklamowe lub jakieś inne zamówienie, utwórz dla niego indeks. Można to zrobić za pomocą std :: set z iteratorów list (lub multiset), chociaż zachowaj to przy każdej modyfikacji listy.

6

Poza tym przy użyciu std :: find (od algorytmu), można również użyć std::find_if (co jest IMO lepiej niż std :: find) lub innego algorytmu znajdowania z this list


#include <list> 
#include <algorithm> 
#include <iostream> 

int main() 
{ 
    std::list<int> myList{ 5, 19, 34, 3, 33 }; 


    auto it = std::find_if(std::begin(myList), 
          std::end(myList), 
          [&](const int v){ return 0 == (v % 17); }); 

    if (myList.end() == it) 
    { 
     std::cout << "item not found" << std::endl; 
    } 
    else 
    { 
     const int pos = std::distance(myList.begin(), it) + 1; 
     std::cout << "item divisible by 17 found at position " << pos << std::endl; 
    } 
} 
+0

Dlaczego find_if jest lepszy? Jeśli szukasz elementu pasującego do równości, czy mówisz, że nie używałbyś find i zamiast tego używałeś find_if? Find_if pozwala na niestandardowe wyszukiwanie, ale jeśli musiałbyś zmieścić się w jakimś okropnym funktorze, by szukać równych sobie, kod sprawiałby wrażenie bardzo brzydkiego w porównaniu do używania find. – CashCow

+1

@CashCow Wszystko zależy od tego, jaki typ elementu znajduje się w wektorze lub na liście. Czasem nie można użyć std :: find. –

+0

Tak, czasami potrzebujesz find_if, dlatego jest częścią biblioteki, ale to nie czyni go "lepszym", tak, że używałbyś go nawet, gdy działa std :: find. – CashCow

Powiązane problemy