Advertisement
RobertDeMilo

BB3.1 Введение

Jun 13th, 2024
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.21 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <optional>
  4. #include <vector>
  5. #include <map>
  6. #include <unordered_map>
  7.  
  8. using namespace std;
  9.  
  10. struct Record
  11. {
  12.     string id;
  13.     string title;
  14.     string user;
  15.     int timestamp;
  16.     int karma;
  17. };
  18.  
  19. class Database
  20. {
  21. public:
  22.      
  23.     bool Put(const Record& record)
  24.     {
  25.         auto [it, inserted] = storage.insert({ record.id, Data{record,{},{},{} } });
  26.  
  27.         if (!inserted)
  28.         {
  29.             return false;
  30.         }
  31.  
  32.         auto& data = it->second;
  33.  
  34.         const Record* ptr = &data.record;
  35.  
  36.         data.timestamp_iter_ = timestamp_index.insert({ record.timestamp, ptr });
  37.  
  38.         data.karma_iter_ = karma_index.insert({ record.karma, ptr });
  39.  
  40.         data.user_iter_ = user_index.insert({ record.user,ptr });
  41.  
  42.         cache.reset();
  43.  
  44.         return true;
  45.     }
  46.  
  47.     const Record* GetById(const string& id) const
  48.     {
  49.         auto it = storage.find(id);
  50.  
  51.         if (it == storage.end())
  52.         {
  53.             return nullptr;
  54.         }
  55.         return &it->second.record;
  56.     }
  57.  
  58.     bool Erase(const string& id)
  59.     {
  60.         auto it = storage.find(id);
  61.  
  62.         if (it == storage.end())
  63.         {
  64.             return false;
  65.         }
  66.  
  67.         const auto& data = it->second;
  68.  
  69.         timestamp_index.erase(data.timestamp_iter_);
  70.  
  71.         karma_index.erase(data.karma_iter_);
  72.  
  73.         user_index.erase(data.user_iter_);
  74.  
  75.         storage.erase(it);
  76.  
  77.         cache.reset();
  78.  
  79.         return true;
  80.     }
  81.  
  82.     template<typename CallBack>
  83.     void RangeByTimestamp(int low, int high, const CallBack& callback) const
  84.     {
  85.         auto it_begin = timestamp_index.lower_bound(low);
  86.         auto it_end = timestamp_index.upper_bound(high);
  87.  
  88.         for (auto it = it_begin(); it!- it_end(); ++it)
  89.         {
  90.             if (!callBack(*it->second))
  91.             {
  92.                 break;
  93.             }
  94.         }
  95.     }
  96.  
  97.     template<typename CallBack>
  98.     void RangeByKarma(int low, int high, const CallBack& callback) /*const*/
  99.     {
  100.         if (!cache || cache->low != low || cache->high != high)
  101.         {
  102.             cache = Cache{ low,high, karma_index.lower_bound(low) , karma_index.upper_bound(high) };
  103.         }
  104.         for (auto it = cache->begin; it != cache->end; ++it)
  105.         {
  106.             if (!callBack(*it->second))
  107.             {
  108.                 break;
  109.             }
  110.         }
  111.  
  112.         //O (log N)
  113.         /*auto it_begin = karma_index.lower_bound(low);
  114.         auto it_end = karma_index.upper_bound(high);*/
  115.         // O(K)
  116.         /*for (auto it = it_begin; it != it_end; ++it)
  117.         {
  118.             if (!callBack(*it->second))
  119.             {
  120.                 break;
  121.             }
  122.         }*/
  123.     }
  124.  
  125.     template <typename CallBack>
  126.     void AllByUser(const string& user, const CallBack& callback) const
  127.     {
  128.         auto [it_begin, it_end] = user_index.equal_range(----);/////?????????????????????
  129.  
  130.         for (auto it = it_begin(); it != it_end(); ++it)
  131.         {
  132.             if (!callBack(*it->second))
  133.             {
  134.                 break;
  135.             }
  136.         }
  137.     }
  138.  
  139. private:
  140.  
  141.     template<typename Type>
  142.     using Index = multimap <Type, const Record*>;
  143.  
  144.     struct Data
  145.     {
  146.         Record record;
  147.         Index<int> ::iterator timestamp_iter_;
  148.         Index<int> ::iterator karma_iter_;
  149.         Index<string> ::iterator user_iter_;
  150.     };
  151.  
  152. private:
  153.     unordered_map<string, Data> storage;
  154.     Index <int> timestamp_index;
  155.     Index <int> karma_index;
  156.     Index <string> user_index;
  157.  
  158.     struct Cache
  159.     {
  160.         int low, high;
  161.         Index<int>::const_iterator begin, end;
  162.     };
  163.  
  164.     std::optional<Cache> cache;
  165. };
  166.  
  167. int FindMinimalKarma(/*const*/ Database& db);
  168.  
  169. int FindMinimalKarma(/*const*/ Database& db)
  170. {
  171.     int result = numeric_limits<int>::max();
  172.     db.RangeByKarma(numeric_limits<int>::min(), numeric_limits<int>::max(), [&](const Record& r)
  173.         {
  174.             result = std::min(result, r.karma);
  175.             return false;
  176.         });
  177.     return result;
  178. }
  179.  
  180. vector<string> FindUsersWithGivenKarma(/*const*/ Database& db, int value);
  181. vector<string> FindUsersWithGivenKarma(/*const*/ Database& db, int value)
  182. {
  183.     vector<string> result;
  184.     db.RangeByKarma(value, value, [&result](const Record& r)
  185.         {
  186.             result.push_back(r.id);
  187.             return true;
  188.         });
  189.  
  190.     return result;
  191. }
  192.  
  193. vector<string> WorstFiveUsers(/*const*/ Database& db);
  194. vector<string> WorstFiveUsers(/*const*/ Database& db)
  195. {
  196.     vector<string> result;
  197.     db.RangeByKarma(numeric_limits<int>::min(), numeric_limits<int>::max(), [&](const Record& r)
  198.         {
  199.             result.push_back(r.id);
  200.             return result.size() < 5;
  201.         });
  202.     return result;
  203. }
  204.  
  205. void TestRangeBoundaries()
  206. {
  207.     const int good_karma = 1000;
  208.     const int bad_karma = -10;
  209.  
  210.     Database db;
  211.     db.Put({ "id1","Hello there","master",153,good_karma });
  212.     db.Put({ "id2","O>>-<","general2",153,bad_karma });
  213.  
  214.     int count = 0;
  215.     db.RangeByKarma(bad_karma, good_karma, [&count](const Record&) {++count; return true; });
  216.     //ASSERT_EQUAL(2, count);
  217. }
  218.  
  219. void TestSameUser()
  220. {
  221.     Database db;
  222.     db.Put({ "id1", "Don't sell", "master", 153, 1000 });
  223.     db.Put({ "id2", "Rethink life","master", 153, 2000 });
  224.  
  225.     int count = 0;
  226.     db.AllByUser("master", [&count](const Record&) {++count; return true; });
  227.     //ASSERT_EQUAL(2, count);
  228. }
  229.  
  230. void TestReplacement()
  231. {
  232.     const string final_body = "Feeling sad";
  233.  
  234.     Database db;
  235.     db.Put({ "id", "Have a hand", "not-master", 153, 10 });
  236.     db.Erase("id");
  237.     db.Put({ "id", final_body, "not-master", 153, -10 });
  238.  
  239.     auto record = db.GetById("id");
  240.     //ASSERT(record != nullptr);
  241.     //ASSERT_EQUAL(final_body, record->title);
  242. }
  243.  
  244. int main()
  245. {
  246.     //TestRunner tr;
  247.     //RUN_TEST(tr, TestRangeBoundaries);
  248.     //RUN_TEST(tr, TestSameUser);
  249.     //RUN_TEST(tr, TestReplacement);
  250.  
  251.     Database db;
  252.     FindMinimalKarma(db);
  253.     FindUsersWithGivenKarma(db, 100);
  254.     WorstFiveUsers(db);
  255.    
  256.     return 0;
  257. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement