Reputation: 969
I have with myself n
integers. I am given with starting value(SV)
and ending value(EV)
, I need to delete the values that lie within the range of these values. The starting value as well the ending value may not exist in the set of n integers. This I need to do in O(No. Of elements deleted)
. Container such as vector
of integers is failing since I need to B.Search and get the iterator that is greater than equal to the SV
and for EV
as well which takes an additional time of Log n
. Any approach appreciated.
Edit : I was even thinking of using maps, storing the values as keys, and erasing on the basis of those key values. But the problem again is that the operation lower_bound
and upper_bound
occur in log
time.
Upvotes: 0
Views: 284
Reputation: 8589
As Marek R suggested there is std::multiset
.
Complexity of the whole exercise is O(log(values.size()+std::distance(first,last)) where that distance is 'number of elements erased'.
It's difficult to see how you can beat that. At the end of it there is always going to be something that increases with the size of the container and log of it is a good deal!
#include <iostream>
#include <set>
void dump(const std::multiset<int>& values);
int main() {
std::multiset<int> values;
values.insert(5);
values.insert(7);
values.insert(9);
values.insert(11);
values.insert(8);
values.insert(8);
values.insert(76);
dump(values);
auto first=values.lower_bound(7);
auto last=values.upper_bound(10);
values.erase(first,last);
dump(values);
return 0;
}
void dump(const std::multiset<int>& values){
auto flag=false;
std::cout<<'{';
for(auto curr : values){
if(flag){
std::cout<<',';
}else{
flag=true;
}
std::cout<< curr;
}
std::cout<<'}'<<std::endl;
}
Upvotes: 0
Reputation: 117926
You can use the erase-remove idiom with std::remove_if
to check if each value is between the two bounds.
#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> values = {1,2,3,4,5,6,7,8,9};
int start = 3;
int stop = 7;
values.erase(std::remove_if(values.begin(),
values.end(),
[start, stop](int i){ return i > start && i < stop; }),
values.end());
for (auto i : values)
{
std::cout << i << " ";
}
}
1 2 3 7 8 9
Upvotes: 0
Reputation: 38052
If you need keep order in container just use:
set
http://www.cplusplus.com/reference/set/set/
or multiset
http://www.cplusplus.com/reference/set/multiset/ if values can repeat.
Both have lower_bound
and upper_bound
functionality.
Upvotes: 3