Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <map>
- template <typename K, typename V>
- class interval_map
- {
- V m_ValBegin;
- std::map<K, V> m_map;
- public:
- interval_map(V const &val) : m_ValBegin(val)
- {
- }
- // Assign value val to interval [keyBegin, keyEnd).
- void assign(K const &keyBegin, K const &keyEnd, V const &val)
- {
- if (!(keyBegin < keyEnd))
- return;
- // Classic case: map is empty
- if (m_map.empty())
- {
- m_map[keyBegin] = val;
- m_map[keyEnd] = m_ValBegin;
- return;
- }
- // Find the iterators that represent the intervals to update
- auto itBegin = m_map.lower_bound(keyBegin);
- auto itEnd = m_map.lower_bound(keyEnd);
- // Handle the case when the previous interval has the same value
- if (itBegin != m_map.begin())
- {
- auto itPrev = std::prev(itBegin);
- if (itPrev->second == val)
- {
- // If the previous interval already has the same value, we don't need to insert a new entry
- itBegin = itPrev;
- }
- else if (itPrev->first == keyBegin)
- {
- // If the previous interval's start matches keyBegin, update it and erase the current interval
- itBegin = itPrev;
- itBegin->second = val;
- }
- }
- // Handle the case when the end of the current interval matches keyEnd
- if (itEnd != m_map.begin() && (--itEnd)->first == keyEnd)
- {
- // If the end of the current interval matches keyEnd, update it
- itEnd->second = val;
- return;
- }
- else
- {
- // Insert a new interval for [keyBegin, keyEnd)
- V new_value = (itEnd == m_map.end()) ? m_ValBegin : itEnd->second;
- m_map[keyBegin] = val;
- m_map[keyEnd] = new_value;
- }
- // Erase any intervals completely covered by the new one
- itBegin = m_map.find(keyBegin);
- itEnd = m_map.lower_bound(keyEnd);
- if (itBegin != itEnd)
- {
- m_map.erase(std::next(itBegin), itEnd);
- }
- auto leftSide = std::prev(itBegin);
- auto rightSide = std::next(itBegin);
- // merging:
- if (itBegin->second == rightSide->second)
- {
- m_map.erase(rightSide);
- }
- if (itBegin->second == leftSide->second)
- {
- m_map.erase(itBegin);
- }
- }
- V const &operator[](K const &key) const
- {
- auto it = m_map.upper_bound(key);
- if (it == m_map.begin())
- {
- return m_ValBegin;
- }
- else
- {
- return (--it)->second;
- }
- }
- const std::map<K, V> &getMap() const { return this->m_map; }
- };
- template <typename K, typename V>
- void printIntervalMap(const interval_map<K, V> &imap)
- {
- const std::map<K, V> &m = imap.getMap();
- std::cout << "{" << std::endl;
- for (auto pair : m)
- {
- std::cout << "\t(" << pair.first << ", " << pair.second << ")" << std::endl;
- }
- std::cout << "}" << std::endl;
- }
- int main()
- {
- interval_map<int, char> mp('I');
- mp.assign(1, 8, 'a');
- mp.assign(8, 14, 'b');
- printIntervalMap(mp);
- mp.assign(6, 9, 'c');
- mp.assign(9, 14, 'c');
- printIntervalMap(mp);
- // {(1, a), (6, 'c'), (9, 'b'), (14, 'I')}
- }
- /*
- void assign(K const &keyBegin, K const &keyEnd, V const &val)
- {
- if (!(keyBegin < keyEnd))
- return;
- // classic case map is empty
- if (this->m_map.empty())
- {
- this->m_map[keyBegin] = val;
- this->m_map[keyEnd] = this->m_ValBegin;
- return;
- }
- // map is not empty, atleast 2 elements are there. [2 intervals]
- // lower_bound -> Iterator pointing to the first element that is not less than key.
- // If no such element is found, a past-the-end iterator. [map.end()]
- // important knowledge -> after insertion, the iterator stands on the same element
- // TODO: before erasing -> create a function to try and 'merge_intervals' only to adjacent elements
- auto left_iterator = this->m_map.lower_bound(keyBegin); // get first that is bigger / equal to keyBegin
- // now two cases:
- if (left_iterator != this->m_map.end())
- {
- // we cannot go one step backwards
- if (left_iterator == this->m_map.begin())
- {
- // ex: add(-1, 2, 'c') with map = {(1,'a'), (8, 'b'), (14, init)}
- // we will make it map = {(-1, 'c'), (2, 'a'), (8, 'b'), (14, init)}
- V moving_value = left_iterator->second;
- K moving_key = left_iterator->key;
- this->m_map[keyBegin] = val;
- this->m_map[keyEnd] = moving_value;
- this->m_map.erase(left_iterator);
- }
- // we can go one step backwards
- else
- {
- --left_iterator;
- // now left_iterator->first is the biggest key which is smaller than keyBegin.
- this->m_map[keyBegin] = val;
- }
- }
- else // left_iterator == this->m_map.end
- // what does it mean? it means that there is no such element bigger / equal to keyBegin
- // meaning when we reach this place we add to the right side end...
- {
- this->m_map[keyBegin] = val;
- this->m_map[keyEnd] = this->m_ValBegin;
- }
- auto right_iterator = this->m_map.lower_bound(keyEnd);
- // two cases
- // right_iterator is not end
- if (right_iterator != this->m_map.end())
- {
- if (right_iterator != this->m_map.begin())
- // can go one step backwards
- {
- --right_iterator;
- if (right_iterator->first)
- }
- else
- // cannot go one step backwards
- {
- }
- }
- // right_iterator is end
- else
- {
- }
- }
- */
Advertisement
Add Comment
Please, Sign In to add comment