Make implementation follow assignment rules
Some checks failed
ci/woodpecker/push/check Pipeline failed
Some checks failed
ci/woodpecker/push/check Pipeline failed
The assignment wants us to use exactly *one* O(log(N)) call. Hence the single usage of `upper_bound`. It also wants us to use a minimal amount of operations on `K` and `V` values in the map. Finally it asks us to make the answer simple.
This commit is contained in:
parent
bdccd17936
commit
dc3408524b
|
@ -15,26 +15,45 @@ public:
|
|||
if (!(begin < end))
|
||||
return;
|
||||
|
||||
auto const end_val = (*this)[end];
|
||||
underlying_.erase(underlying_.lower_bound(begin),
|
||||
underlying_.upper_bound(end));
|
||||
if (!((*this)[begin] == val))
|
||||
underlying_.insert({begin, val});
|
||||
if (!((*this)[end] == end_val))
|
||||
underlying_.insert({end, end_val});
|
||||
auto it = underlying_.upper_bound(end);
|
||||
auto const end_val = at_upper_bound(it);
|
||||
|
||||
bool insert_begin = !(val == init_);
|
||||
|
||||
while (it != underlying_.begin()) {
|
||||
it = std::prev(it);
|
||||
auto begin_found = it->first < begin;
|
||||
if (begin_found) {
|
||||
insert_begin = !(val == it->second);
|
||||
break;
|
||||
}
|
||||
if (it != underlying_.end())
|
||||
// Account for up-coming `std::prev` with `++`
|
||||
underlying_.erase(it++);
|
||||
}
|
||||
|
||||
if (insert_begin)
|
||||
it = underlying_.insert(it, {begin, val});
|
||||
// Get the proper upper-bound for `end`
|
||||
it = (it == underlying_.end()) ? it : std::next(it);
|
||||
if (!(at_upper_bound(it) == end_val))
|
||||
underlying_.insert(it, {end, end_val});
|
||||
}
|
||||
|
||||
V const& operator[](K const& key) const {
|
||||
auto it = underlying_.upper_bound(key);
|
||||
if (it == underlying_.begin())
|
||||
return init_;
|
||||
return std::prev(it)->second;
|
||||
return at_upper_bound(underlying_.upper_bound(key));
|
||||
}
|
||||
|
||||
// Used in testing
|
||||
friend class ::IntervalMapTest;
|
||||
|
||||
private:
|
||||
V const& at_upper_bound(std::map<K, V>::const_iterator it) const {
|
||||
if (it == underlying_.begin())
|
||||
return init_;
|
||||
return std::prev(it)->second;
|
||||
}
|
||||
|
||||
V init_;
|
||||
std::map<K, V> underlying_{};
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue