Kaip patikrinti, ar elementas yra std :: set?

Kaip patvirtinate, kad elementas yra rinkinyje?

Ar yra paprastesnis šio kodo ekvivalentas:

 myset.find(x) != myset.end() 
257
09 нояб. nustatė fulmicoton 09 nov. 2009-11-09 16:46 '09, 16:46, 2009-11-09 16:46
@ 10 atsakymų

Tipiškas būdas patikrinti, ar yra daugelio STL konteinerių prieinamumas:

 const bool is_in = container.find(element) != container.end(); 
311
09 нояб. Atsakymas atsipalaidavęs 09.11. 2009-11-09 16:49 '09 at 4:49 PM 2009-11-09 16:49

Kitas būdas tiesiog pasakyti, jei yra elementas, yra patikrinti count()

 if (myset.count(x)) { // x is in the set, count is 1 } else { // count zero, ie x not in the set } 
border=0 Tačiau daugeliu atvejų man reikia prieigos prie elemento, kuriame aš tikrinu jos egzistavimą.

Todėl vis dar turiu rasti iteratorių. Tada, žinoma, geriau palyginti ją su end .

 set< X >::iterator it = myset.find(x); if (it != myset.end()) { // do something with *it } 
160
09 нояб. Atsakymas pateikiamas Pieterio lapkričio 9 d. 2009-11-09 18:42 '09 18:42 2009-11-09 18:42

Tiesiog paaiškinkite, kodėl šiuose konteinerių tipuose nėra nario, kaip contains() , nes jis atvers jums neefektyvų kodą. Toks metodas gali tiesiog tai padaryti - this->find(key) != this->end() viduje, bet apsvarstyti, ką darote, kai raktas yra tikrai; daugeliu atvejų jūs norėsite gauti elementą ir kažką daryti su juo. Tai reiškia, kad jūs turite padaryti antrą find() , kuris yra neefektyvus. Geriau naudoti paiešką tiesiogiai, kad galėtumėte talpinti savo rezultatą, pavyzdžiui:

 Container::const_iterator it = myContainer.find(key); if (it != myContainer.end()) { // Do something with it, no more lookup needed. } else { // Key was not present. } 

Žinoma, jei nerūpi efektyvumas, visada galite sumažinti savo pačių skaičių, bet šiuo atveju tikriausiai neturėtumėte naudoti C ++ ...;)

34
09 нояб. Atsakymą pateikė Tim 09 Nov. 2009-11-09 19:26 '09 19:26 2009-11-09 19:26

Jei ketinate pridėti turinio funkciją, tai gali atrodyti taip:

 #include <algorithm> #include <iterator> template<class TInputIterator, class T> inline bool contains(TInputIterator first, TInputIterator last, const T value) { return std::find(first, last, value) != last; } template<class TContainer, class T> inline bool contains(const TContainer container, const T value) { // This works with more containers but requires std::begin and std::end // from C++0x, which you can get either: // 1. By using a C++0x compiler or // 2. Including the utility functions below. return contains(std::begin(container), std::end(container), value); // This works pre-C++0x (and without the utility functions below, but doesn't // work for fixed-length arrays. //return contains(container.begin(), container.end(), value); } template<class T> inline bool contains(const std::set<T> container, const T value) { return container.find(value) != container.end(); } 

Tai veikia su std::set , kitais STL konteineriais ir net fiksuoto ilgio matricomis:

 void test() { std::set<int> set; set.insert(1); set.insert(4); assert(!contains(set, 3)); int set2[] = { 1, 2, 3 }; assert(contains(set2, 3)); } 

Redaguoti:

Kaip pažymėta komentaruose, aš netyčia naudoju naują funkciją C ++ 0x ( std::begin ir std::end ). Čia yra beveik trivialus VS2010 įgyvendinimas:

 namespace std { template<class _Container> inline typename _Container::iterator begin(_Container _Cont) { // get beginning of sequence return (_Cont.begin()); } template<class _Container> inline typename _Container::const_iterator begin(const _Container _Cont) { // get beginning of sequence return (_Cont.begin()); } template<class _Container> inline typename _Container::iterator end(_Container _Cont) { // get end of sequence return (_Cont.end()); } template<class _Container> inline typename _Container::const_iterator end(const _Container _Cont) { // get end of sequence return (_Cont.end()); } template<class _Ty, size_t _Size> inline _Ty *begin(_Ty ( { // get beginning of array return ( } template<class _Ty, size_t _Size> inline _Ty *end(_Ty ( { // get end of array return ( + _Size); } } 
6
09 нояб. atsakymą pateikė Sam Harwell 09 lapkričio. 2009-11-09 19:36 '09 19:36 2009-11-09 19:36

Taip pat galite patikrinti, ar elementas įdiegtas elemento diegimo metu. Vieno elemento versija grąžina porą su nario pora: pirma, nustatomas iteratorius, nurodantis arba naujai įdėtą elementą, arba lygiavertį elementą, jau įdiegtą rinkinyje. Pora :: antrasis poros elementas yra teisingas, jei naujas elementas buvo įterptas arba klaidingas, jei lygiavertis elementas jau yra.

Pavyzdžiui: tarkime, kad rinkinyje jau yra 20.

  std::set<int> myset; std::set<int>::iterator it; std::pair<std::set<int>::iterator,bool> ret; ret=myset.insert(20); if(ret.second==false) { //do nothing } else { //do something } it=ret.first //points to element 20 already in set. 

Jei elementas yra vėl įdėtas, nei pora: pirmiausia nurodo naujo elemento poziciją rinkinyje.

3
15 сент. Atsakymą pateikė Prashant Shubham rugsėjo 15 d. 2016-09-15 20:42 '16 at 8:42 pm 2016-09-15 20:42

Parašykite savo:

 template<class T> bool checkElementIsInSet(const T elem, const std::set<T> container) { return container.find(elem) != container.end(); } 
2
09 нояб. atsakymas duotas stefaanv . 2009-11-09 16:59 '09, 16:59 2009-11-09 16:59

aš naudoju

 if(!my_set.count(that_element)) //Element is present... ; 

Bet tai nėra tokia veiksminga kaip

 if(my_set.find(that_element)!=my_set.end()) ....; 

Mano versija sutaupo laiko tik rašydama kodą. Man tai patinka konkurenciniam kodavimui.

2
03 февр. atsakymą pateikė Manas Bondale 03 vasaris. 2018-02-03 13:35 '18, 13:35 ; 2018-02-03 13:35

C ++ 20, mes pagaliau gauname std::set::contains metodas.

 #include <iostream> #include <string> #include <set> int main() { std::set<std::string> example = {"Do", "not", "panic", "!!!"}; if(example.contains("panic")) { std::cout << "Found\n"; } else { std::cout << "Not found\n"; } } 
1
15 янв. Atsakymą pateikė Denis Sablukov sausio 15 d. 2019-01-15 14:20 '19, 14:20 pm 2019-01-15 14:20

Aš sugebėjau parašyti bendrą std::list ir std::vector .

 template<typename T> bool contains( const list<T> container, const T elt ) { return find( container.begin(), container.end(), elt ) != container.end() ; } template<typename T> bool contains( const vector<T> container, const T elt ) { return find( container.begin(), container.end(), elt ) != container.end() ; } // use: if( contains( yourList, itemInList ) ) // then do something 

Tai šiek tiek supaprastina sintaksę.

Bet aš negalėjau naudoti šablono šablono , kad šis darbas būtų savavališkas.

 // NOT WORKING: template<template<class> class STLContainer, class T> bool contains( STLContainer<T> container, T elt ) { return find( container.begin(), container.end(), elt ) != container.end() ; } 

Bet kokios pastabos dėl paskutinio atsakymo tobulinimo būtų gražios.

0
04 мая '13 в 22:17 2013-05-04 22:17 atsakymas pateikiamas bobobobo 04 gegužės 13 d. 10:17 val. 2013-05-04 22:17

// bendra sintaksė

  set<int>::iterator ii = find(set1.begin(),set1.end(),"element to be searched"); 

/ * apatiniame kode, bandau rasti elementą 4 į ir int, jei jis yra ar ne * /

 set<int>::iterator ii = find(set1.begin(),set1.end(),4); if(ii!=set1.end()) { cout<<"element found"; set1.erase(ii);// in case you want to erase that element from set. } 
0
04 сент. atsakymas duotas sanjeev 04 sep . 2017-09-04 14:27 '17, 14:27 pm 2017-09-04 14:27

Kiti klausimai apie arba Užduoti klausimą