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
dequeprvectorintoset
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
trueorfalse~~from C++ 20
- returns
- use
count()for checking element present or not: ⇢⇢ ☠️ Don't usebinary_search()☠️- returns
1or0
- 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 --trueorfalsecount()for element present or not --1or0lower_bound()⇢ container's ownlower_bound()upper_bound()⇢ container's ownupper_bound()equal_range()⇢ container's ownequal_range()unordered_set,unordered_multiset,unordered_map,unordered_multimapdon'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_searchhas 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::setandstd::multisethave a “find” function, whilevectordoesn’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 + 500with 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 inmaporsetreturns 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. Assetcan contain only unique elements, so occurrence count of the given element can be only0or1i.e, If found then 1 else 0
count()returns1if thesetormapcontains the element and0if it doesn't.
contains() ~~ C++ 20
Time Complexity is :~ O(log n)
contains()returnstrueif thesetormapcontains the element andfalseif it doesn't.
lower_bound()
unodered_sethas no memberlower_boundorupper_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()returnsiteratorand hence, we MUSTsubtractv.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_sethas no memberlower_boundorupper_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()'