Advertisement
bartekltg

stable_unique

Sep 18th, 2015
224
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.58 KB | None | 0 0
  1. #include <iostream>
  2. #include <unordered_set>
  3. #include <set>
  4. #include <vector>
  5. #include <random>
  6. #include <algorithm>
  7. #include <chrono>
  8.  
  9. using namespace std;
  10.  
  11.  
  12. // iterator to praktycznie wskaźnik; można go przesuwać po elementach przez ++ i --
  13. // "*iterator" to dereferencja "wskaźnika", czyli dostęp do wartośći, na którą pokazuje.
  14. //to samo co pascalowskie "iterator^"
  15.  
  16. template <class iter>
  17. iter stable_unique_1 ( iter first, iter last )
  18. {
  19.     unordered_set<int> temp; //zbiór użytych, pusty na poczatku
  20.     iter writer(first); //tym będziemy czytac kazdy element
  21.     iter reader(first); // tu bedziemy zapisywac tylko unikalne. poczatkowo oba wskazniki idą razem
  22.     while (reader!= last) { //czy to już koniec
  23.         if (temp.count(*reader)==0){  //element pokazywany przez reader nie istenije w temp
  24.             *writer=*reader; // kopiuj unikalny element na pierwsze należne miejsce
  25.             writer++; //przesuń owo miejsce
  26.             temp.insert(*reader); //dodajemy do zbioru już użytych
  27.         }
  28.         reader++;// kroczek
  29.     }
  30.     return writer; // zwracam iterator (wskaźnik) za ostatnim sensownym elementem,
  31.     //nie zmieniam wielkośći tablicy, tym sie zajme poziom wyzej,
  32.     //taka konwencja, patrz idiom remove-erase
  33. }
  34.  
  35.  
  36. template <class iter>
  37. iter stable_unique_2 ( iter first, iter last )
  38. {
  39.     set<int> temp; //zbiór użytych
  40.     iter writer(first);
  41.     iter reader(first);
  42.     while (reader!= last) { //czy to już koniec
  43.         if (temp.count(*reader)==0){  //element pokazywany przez reader nie istenije ww temp
  44.             *writer=*reader; // kopiuj unikalny element na pierwsze należne miejsce
  45.             writer++; //przesuń owo miejsce
  46.             temp.insert(*reader); //dodajemy do zbioru już użytych
  47.         }
  48.         reader++;// kroczek
  49.     }
  50.     return writer;
  51. }
  52.  
  53. template <class iter>
  54. iter stable_unique_3 ( iter first, iter last )
  55. {
  56.     iter writer(first);
  57.     iter reader(first);
  58.     while (reader!= last)  //czy to już koniec
  59.     {
  60.         if (count(first, writer, *reader)==0){  //elementu poszukiwany (wskazywany przez reader) nie ma
  61.                                                   //w już przetworzonym zakresie (od [first a przed writer)
  62.                                                 //lepiej byłoby użyć funkcji find:
  63.                                                 //find(first, writer, *reader)==writer) ale warunek trochę zaciemnia:)
  64.             *writer=*reader; // kopiuj unikalny element na pierwsze należne miejsce
  65.             writer++; //przesuń owo miejsce
  66.         }
  67.         reader++;// kroczek
  68.     }
  69.     return writer;
  70. }
  71.  
  72. template <class iter>
  73. iter stable_unique_4 ( iter first, iter last )
  74. {
  75.     unordered_set<int> temp(first, last); //zbiór nieużytych
  76.     iter writer(first);
  77.     iter reader(first);
  78.     while (reader!= last) { //czy to już koniec
  79.         if (temp.count(*reader)>0){  //element pokazywany przez reader istenije w temp
  80.             *writer=*reader; // kopiuj unikalny element na pierwsze należne miejsce
  81.             writer++; //przesuń owo miejsce
  82.             temp.erase(*reader); //dodajemy do zbioru już użytych
  83.         }
  84.         reader++;// kroczek
  85.     }
  86.     return writer;
  87. }
  88.  
  89.  
  90. template <class iter>
  91. iter unstable_unique ( iter first, iter last )
  92. {
  93.     sort(first, last);
  94.     return unique(first, last);
  95. }
  96.  
  97.  
  98. template <class iter>
  99. iter stable_unique_5 ( iter first, iter last )
  100. {
  101.     vector <int> sorted(first, last);
  102.     vector <uint8_t> visited(sorted.size(),0);
  103.     sort(sorted.begin(), sorted.end());
  104.  
  105.     iter writer(first);
  106.     iter reader(first);
  107.     while (reader!= last) { //czy to już koniec
  108.         auto it = lower_bound(sorted.begin(), sorted.end(),*reader);
  109.         if ( visited[ it-sorted.begin() ]==0  ){
  110.             *writer=*reader; // kopiuj unikalny element na pierwsze należne miejsce
  111.             writer++; //przesuń owo miejsce
  112.             visited[ it-sorted.begin() ] = 1;
  113.         }
  114.         reader++;// kroczek
  115.     }
  116.     return writer;
  117.  
  118. }
  119.  
  120.  
  121.  
  122.  
  123.  
  124. class stoper
  125. {
  126.     chrono::time_point<chrono::high_resolution_clock> a,b;
  127. public:
  128.     void start(){a = chrono::high_resolution_clock::now();}
  129.     void stop() {b = chrono::high_resolution_clock::now();}
  130.     double value()
  131.     {
  132.         chrono::duration<double> elapsed_seconds = b-a;
  133.         return elapsed_seconds.count();
  134.     }
  135. };
  136.  
  137.  
  138. template <typename F >
  139. void test (F f, string s)
  140. {
  141.     cout<<s<<endl<<"poprawność:"<<endl; ;
  142.     vector<int> tab = {12,457,12,457,1,56,89,12,11,11,55,11,11,1,457};
  143.     for (auto a:tab)
  144.         cout<<a<<" ";
  145.     cout<<endl;
  146.  
  147.  
  148.     tab.erase( f( tab.begin(),tab.end() ), tab.end()  );
  149.  
  150.     for (auto a:tab)
  151.         cout<<a<<" ";
  152.     cout<<endl<<"szybkość"<<endl;
  153.  
  154.     random_device rd;
  155.     mt19937 gen(rd());
  156.  
  157.     for (int size = 100; size<=100000;size*=10 )
  158.     {
  159.         tab.resize(size);
  160.         generate(tab.begin(), tab.end(), gen);
  161.         stoper st;   st.start();
  162.         for (int i=0; i<100000/size+1;i++)
  163.             tab.erase( f( tab.begin(),tab.end() ), tab.end()  );
  164.         st.stop();
  165.         cout<<size<<" zajelo "<<st.value()/((double)100000/size+1)<<"s"<<endl;
  166.     }
  167.  
  168.     cout<<endl;
  169.  
  170.  
  171. }
  172.  
  173. int main()
  174. {
  175.  
  176.     typedef vector<int>::iterator iter;
  177.     test(  stable_unique_1<iter> ,"hashmapa budowana" );
  178.     test(  stable_unique_2<iter> , "zbior budowany" );
  179.     test(  stable_unique_4<iter> , "hashmapa usuwana " );
  180.     test(  stable_unique_3<iter> , "naiwne n^2 " );
  181.     test(  unstable_unique<iter> , "sortowanie " );
  182.     test(  stable_unique_5<iter> , "sortowanie stab" );
  183.     return 0;
  184. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement