आप कैसे जांचते हैं कि एक तत्व एक सेट में है?
क्या निम्नलिखित कोड के बराबर सरल है:
myset.find(x) != myset.end()
आप कैसे जांचते हैं कि एक तत्व एक सेट में है?
क्या निम्नलिखित कोड के बराबर सरल है:
myset.find(x) != myset.end()
जवाबों:
विशिष्ट तरीका जैसे कई एसटीएल कंटेनरों में होने की जाँच करने के लिए std::map
, std::set
... है:
const bool is_in = container.find(element) != container.end();
std::find(container.begin(), container.end(), element) != container.end()
; O (N) समस्या बनी हुई है, ...
if(container.find(foo) == container.end())
पहले तत्व को खोजने के लिए ट्री लुकअप करने की आवश्यकता है - यदि नहीं मिला है, तो आपको सही इंसर्शन स्थान खोजने के लिए एक दूसरे ट्री लुकअप को करने की आवश्यकता है। मूल संस्करण if(container.insert(foo).second) {...}
में आकर्षण है कि इसे सिर्फ एक ही पेड़ देखने की आवश्यकता है ...
set.contains(x)
कि C ++ 20 मानक में एक बूल देता है। मुझे नहीं पता कि इसे पाने के लिए हमें 2020 तक क्यों ले जाया गया है।
एक तत्व मौजूद है या नहीं, यह बताने का दूसरा तरीका है count()
if (myset.count(x)) {
// x is in the set, count is 1
} else {
// count zero, i.e. x not in the set
}
हालांकि, अधिकांश समय, मैं खुद को उस तत्व तक पहुंच की आवश्यकता महसूस करता हूं जहां मैं इसके अस्तित्व की जांच करता हूं।
तो मैं वैसे भी itter खोजने के लिए होगा। फिर, निश्चित रूप से, इसकी तुलना करना end
बहुत बेहतर है।
set< X >::iterator it = myset.find(x);
if (it != myset.end()) {
// do something with *it
}
सी ++ 20
C ++ 20 सेट में एक contains
फ़ंक्शन मिलता है , इसलिए निम्नानुसार संभव हो जाता है: https://stackoverflow.com/a/54197839/895245
if (myset.contains(x)) {
// x is in the set
} else {
// no x
}
count()
इसके बजाय का उपयोग करना find()
बेहतर नहीं है लेकिन संभावित रूप से बदतर है। ऐसा इसलिए है क्योंकि find()
पहले मैच के बाद वापसी होगी, count()
हमेशा सभी तत्वों पर पुनरावृति होगी।
multiset
और multimap
मैंने सोचा था? हालाँकि अभी भी यह बताना अच्छा है :)
set
एक सदस्य के लिए ही संभव है , जो मेल खाता हो, तो क्या फंक्शन को इस तरह से लागू नहीं किया जाएगा, जैसे कि पहले तत्व का पता लगाने के बाद रुकना है, इस मामले में, जैसा कि पीटर बताते हैं? किसी भी मामले में उपयोगी उत्तर!
count()
कभी भी तेजी से नहीं हो find()
) अभी भी, दूसरा भाग वास्तव में लागू नहीं है std::set
। हालाँकि, मुझे लगता है कि इसके पक्ष में एक और तर्क दिया जा सकता है find()
: यह अधिक अभिव्यंजक है, यानी इस बात पर जोर दिया जाता है कि आप एक तत्व को खोजने की कोशिश कर रहे हैं, जो संख्याओं की संख्या गिनने के बजाय है।
बस स्पष्ट करने के लिए, contains()
इन कंटेनर प्रकारों में कोई सदस्य क्यों नहीं है इसका कारण यह है कि यह आपको अक्षम कोड लिखने के लिए खोल देगा। इस तरह की एक विधि शायद केवल this->find(key) != this->end()
आंतरिक रूप से करेगी , लेकिन विचार करें कि जब कुंजी वास्तव में मौजूद है तो आप क्या करते हैं; ज्यादातर मामलों में आप तब तत्व प्राप्त करना चाहते हैं और इसके साथ कुछ करना चाहते हैं। इसका मतलब है कि आपको दूसरा काम करना होगा find()
, जो अक्षम है। सीधे उपयोग करना बेहतर है, ताकि आप अपना परिणाम कैश कर सकें, जैसे:
auto it = myContainer.find(key);
if (it != myContainer.end())
{
// Do something with it, no more lookup needed.
}
else
{
// Key was not present.
}
बेशक, यदि आप दक्षता के बारे में परवाह नहीं करते हैं, तो आप हमेशा अपना रोल कर सकते हैं, लेकिन उस स्थिति में आप शायद C ++ का उपयोग नहीं करना चाहिए ...);
list::remove
, remove(makes_sense_only_for_vector, iterators)
...)
में सी ++ 20 हम अंत में मिल जाएगा std::set::contains
विधि।
#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";
}
}
यदि आप एक contains
फ़ंक्शन जोड़ने जा रहे हैं , तो यह इस तरह दिख सकता है:
#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();
}
यह std::set
अन्य STL कंटेनरों के साथ काम करता है , और यहां तक कि निश्चित लंबाई वाले सरणियों:
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));
}
जैसा कि टिप्पणियों में बताया गया है, मैंने अनायास ही C ++ 0x ( std::begin
और std::end
) के लिए एक फ़ंक्शन नया उपयोग किया । यहाँ VS2010 से निकट-तुच्छ कार्यान्वयन है:
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 (&_Array)[_Size])
{ // get beginning of array
return (&_Array[0]);
}
template<class _Ty,
size_t _Size> inline
_Ty *end(_Ty (&_Array)[_Size])
{ // get end of array
return (&_Array[0] + _Size);
}
}
std::set
, और याद रखें कि यह केवल उचित है अगर केवल एक चीज जिसे आपको जानना आवश्यक है वह है अस्तित्व।
आप यह भी देख सकते हैं कि तत्व डालने के दौरान कोई तत्व सेट में है या नहीं। एकल तत्व संस्करण एक जोड़ी लौटाता है, जिसके सदस्य जोड़े के साथ :: पहले सेट करने के लिए या तो नए सम्मिलित तत्व या सेट में पहले से ही समतुल्य तत्व की ओर इशारा करते हुए। यदि कोई नया तत्व सम्मिलित किया गया था या यदि पहले से ही समतुल्य तत्व मौजूद था, तो जोड़ी :: जोड़ी में दूसरा तत्व सत्य पर सेट है।
उदाहरण के लिए: मान लीजिए कि सेट में पहले से ही एक तत्व के रूप में 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.
यदि तत्व जोड़ी की तुलना में नया डाला जाता है :: पहले सेट में नए तत्व की स्थिति को इंगित करेगा।
खुद लिखिए:
template<class T>
bool checkElementIsInSet(const T& elem, const std::set<T>& container)
{
return container.find(elem) != container.end();
}
मैं उपयोग करता हूं
if(!my_set.count(that_element)) //Element is present...
;
लेकिन यह उतना कुशल नहीं है
if(my_set.find(that_element)!=my_set.end()) ....;
मेरा संस्करण केवल कोड लिखने में अपना समय बचाता है। मैं इसे प्रतिस्पर्धी कोडिंग के लिए इस तरह से पसंद करता हूं।
count()
। कोई भी यह समझने में असमर्थ है कि बूलियन अभिव्यक्ति में उपयोग किया जाने वाला पूर्णांक-लौटाने वाला फ़ंक्शन गैर-शून्य के लिए परीक्षण कर रहा है, सी / सी ++ मुहावरों के महान समुद्र में कई, कई अन्य निशान हैं। और, जैसा कि ऊपर उल्लेख किया गया है, वास्तव में सेट के लिए उतना ही कुशल होना चाहिए, जो सवाल था।
मैं एक सामान्य contains
कार्य लिखने में सक्षम था std::list
और 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
यह सिंटैक्स को थोड़ा साफ करता है।
लेकिन मैं इस कार्य को मनमाने ढंग से stl कंटेनरों को बनाने के लिए टेम्पलेट टेम्पलेट पैरामीटर जादू का उपयोग नहीं कर सका ।
// 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() ;
}
अंतिम उत्तर को बेहतर बनाने के बारे में कोई भी टिप्पणी अच्छी होगी।
template<typename CONTAINER, typename CONTAINEE> bool contains(const CONTAINER& container, const CONTAINEE& needle) { return find(container.begin(), container.end(), needle) != container.end();
// सामान्य सिंटेक्स
set<int>::iterator ii = find(set1.begin(),set1.end(),"element to be searched");
/ * नीचे दिए गए कोड में मैं तत्व 4 में खोजने की कोशिश कर रहा हूं और अगर यह मौजूद है या नहीं तो int सेट करें * /
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.
}