set
set
is an Associative Container that contains a sorted
set of UNIQUE
objects of type Key. Sorting is done using the key comparison function Compare
. Search
, removal
, and insertion
operations have logarithmic complexity O(long n)
. Sets are usually implemented as red-black trees
Declaration
Initialisation
Initialising set
from vector
set<int> st(vec.begin(), vec.end());
Initialising set
from deque
set<int> st(dequeName.begin(), dequeName.end());
Not available in set
Index Number not available with set
- Element Access using Index Number is not possible
- NO methods are available for element access in
set
insert(positon, begin(), end())
not available with set
insert(positon, begin(), end())
- Can't copy elements from other Data Sructures like
deque
prvector
intoset
Must Refer and Research: https://www.google.com/search?q=element+access+in+set+c%2B%2B&oq=element+access+in+set+c%2B%2B&aqs=chrome..69i57j0i22i30l3j0i390l2.10800j0j7&sourceid=chrome&ie=UTF-8
TO ADD Other Topics
set
Methods
Modifiers
insert()
- Inserts elements or nodes
erase()
clear()
swap()
extract()
merge()
emplace()
emplace_hint()
Lookup
💣 binary_search()
from STL MUST not be used with set
, multiset
, map
, multimap
. 💣
- use
find()
for search element'sIndex No.
- use
contains()
for checking element present or not: ⇢⇢ ☠️ Don't usebinary_search()
☠️- returns
true
orfalse
~~from C++ 20
- returns
- use
count()
for checking element present or not: ⇢⇢ ☠️ Don't usebinary_search()
☠️- returns
1
or0
- returns
💣 binary_search()
from STL MUST not be used with set
, multiset
, map
, multimap
. 💣
binary_search()
becomesO(n)
when used withset
,multiset
,map
,multimap
,unordered_set
,unordered_multiset
,unordered_map
,unordered_multimap
.All the Associative Containers have
O(log n)
alternative ofbinary_search()
↠find()
forIndexNo.
of target search elementcontains()
for element present or not --true
orfalse
count()
for element present or not --1
or0
lower_bound()
⇢ container's ownlower_bound()
upper_bound()
⇢ container's ownupper_bound()
equal_range()
⇢ container's ownequal_range()
unordered_set
,unordered_multiset
,unordered_map
,unordered_multimap
don't havelower_bound()
,upper_bound()
Hence, binary_search()
must not be used with Associative Containers
https://discuss.codechef.com/t/set-find-vs-binary-search-help-needed-asap/23991/6
binary_search
has a logarithmic time complexity only forLegacyRandomAccessIterators
. This is the case ofstd::vector iterators
, for example. Sets/multisets are trees, so their iterators don’t allow random access. This makesbinary_search()
run in linear time, which is significantly slower for a large range. This is whystd::set
andstd::multiset
have a “find
” function, whilevector
doesn’t. They need their own binary search implementation to be able to run in logarithmic time.For instance, if your range spans over 1000 elements,
binary_search()
will want to look at the element at position 500 first. Vector iterators are more or less pointers, it’s easy to dobegin + 500
with pointer arithmetics. Since the elements are sorted, we can remove half of the range with a single comparison. That’s whybinary_search()
is very efficient, with logarithmic complexity.❎ BUT, In a set or multiset, nodes that are neighbors in the tree are not necessarily neighbors in memory. So,
binary_search()
would not even be able to know how many elements are in the range, end - begin is not supported. So the search starts at begin the iterator is incremented, until it reaches a value not lower than the one we are searching for. This is whybinary_search()
has poor performance with sets, and you should use thefind()
function provided by that particular container, that has a more suitable search strategy.
find()
Time Complexity is :~ O(log n)
- element present --
( it != setName.end() )
;- because
find()
funtion inmap
orset
returns Iterator to an element with key equivalent to key. If no such element is found, end() iterator is returned.
- because
- element NOT present --
( it == setName.end() )
;
if (it != setName.end())
{
cout << "Found " << (*it) << endl;
}
set<int> setName = {1, 2, 3, 4};
auto search = setName.find(2); // iterator to store the location
if (search != setName.end()) { // if iterator value is not the end(), i.e. element is present.
// if iterator value == end(), i.e. element is NOT present.
cout << "Found " << (*search) << '\n';
} else {
cout << "Not found\n";
}
count()
Time Complexity is :~ O(log n)
setName.count(targetValue)
count()
accepts the element as argument and search for its number of occurrence count in the set. Asset
can contain only unique elements, so occurrence count of the given element can be only0
or1
i.e, If found then 1 else 0
count()
returns1
if theset
ormap
contains the element and0
if it doesn't.
contains()
~~ C++ 20
Time Complexity is :~ O(log n)
contains()
returnstrue
if theset
ormap
contains the element andfalse
if it doesn't.
lower_bound()
unodered_set
has no memberlower_bound
orupper_bound
Time Complexity is :~ O(log n)
Returns: Iterator pointing to first element equal to or greater than key, or end().
If element/key is present This function returns the first element of a subsequence of elements that matches the given key.
If element not present it returns an iterator pointing to the first element that has a greater value than given key or
end()
if no such element exists.
lower_bound(v.begin(), v.end(), key) - v.begin()
- Must be like this -> lower_bound(v.begin(), v.end(), key)
- v.begin()
becauselower_bound()
returnsiterator
and hence, we MUSTsubtract
v.begin()
from thelower_bound()
if (!binary_search(v.begin(), v.end(), key)) // if element is not present return -1
{
return -1;
}
else
{
return (lower_bound(v.begin(), v.end(), key) - v.begin()); // "lower_bound()" returns `iterator` and hence, we MUST `subtract` `v.begin()` from the `lower_bound()`
}
to get the element
from lower_bound
then use *lowboundIteratorName
set<int> st = {4566, 565465, 56, 557567, 342, 56756};
auto lb = st.lower_bound(342);
cout << "____" << (*lb) << endl
<< endl;
// set is [56 342 4566 56756 557567 565465 ]
/*
Output:
'____342'
*/
upper_bound()
unodered_set
has no memberlower_bound
orupper_bound
Time Complexity is :~ O(log n)
Returns: Iterator pointing to the first element greater than key, or end().
set<int> st = {4566, 565465, 56, 557567, 342, 56756};
auto ub = st.upper_bound(342);
cout << "____" << (*ub) << endl
<< endl;
// set is [56 342 4566 56756 557567 565465 ]
/*
Output:
'____4566'
*/
Common Problems of set
Last Element of a set
*a.rbegin()
auto it = s.end();
thenit--;
// va = [ 1 2 3 4 6 9 12 18 36 ]
// vb = [ 1 2 3 6 9 18 27 54 ]
set<ll> tmp; // declaring empty set
set_intersection(av.begin(), av.end(), bv.begin(), bv.end(), inserter(tmp, tmp.begin())); // inserting all common values of 'set' "av" & "bv" in 'set' "tmp"
// tmp becomes [ 1 2 3 6 9 18 ] ; 'tmp' returns the intersection of "av" & "bv"
cout << *tmp.rbegin() << endl; // 👉 returns the "last" element of the 'set', "*" gives the value at that particular iterator '*tmp.rbegin()'