diff --git a/data_structures/reverse_map.cpp b/data_structures/reverse_map.cpp new file mode 100644 index 00000000000..d4b2e67d346 --- /dev/null +++ b/data_structures/reverse_map.cpp @@ -0,0 +1,100 @@ +/** + * @author asart9O + * Simple reversemap data type + * the goal is - sort map not by key, but by value. + */ +#include /// io +#include +#include /// for multiset +#include +#include +#include +#include // for find_if +#include +using std::map; +using std::multiset; +using std::pair; +using std::vector; +template /// declaring reverse map with key and value. +class ReverseMap +{ + private: ///declaring a backbone map + map> mp; + vector> extract; /// vector to extract to + public: + ///inserting into ReverseMap + void insert(const key& Key, const value& Value) + { + ///We insert key into map with value as key. Value gets sorted, multiset with keys stays. + mp[Value].insert(Key); + } + vector> to_vector() + { + extract.clear(); /// clearing + for(auto entry : mp) + { + value v = entry.first; /// getting value + for(auto k : entry.second) /// iterating through keys + { + /// locate existing pair in exctract + auto it = std::find_if( + extract.begin(), extract.end(), + [&](auto p) {return p.first == k;} + ); + if(it == extract.end()) + { + ///append + extract.emplace_back(k, v); + } + else + { + /// update, add v + it->second += v; + } + } + } + ///sorting by second element + std::sort(extract.begin(), extract.end(), + [](auto a, auto b) + {return a.second < b.second;}); + return extract; + } +}; +void test1() +{ + ReverseMap map; + map.insert(1, 2); + map.insert(234324234, 1); + map.insert(20, 3); + map.insert(2, 2); + vector> expected = { + {234324234, 1}, + {1, 2}, + {2, 2}, + {20, 3} + }; + auto result = map.to_vector(); + assert(result == expected); +} +void test2() +{ + ReverseMap mapy; + mapy.insert(-1, 3); + mapy.insert(5, -20); + mapy.insert(-1, 2); + mapy.insert(1, 0); + vector> expected = { + {5, -20}, + {1, 0}, + {-1, 5} + }; + auto result = mapy.to_vector(); + assert(result == expected); +} +int main() +{ + ///running tests. + test1(); + test2(); + return 0; +}