Guest User

Untitled

a guest
Sep 19th, 2015
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.88 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. #include <cstring>
  9.  
  10. using namespace std;
  11.  
  12. #define MAX_SIZE (100000000)
  13.  
  14. // iterator to praktycznie wskaźnik; można go przesuwać po elementach przez ++ i --
  15. // "*iterator" to dereferencja "wskaźnika", czyli dostęp do wartośći, na którą pokazuje.
  16. //to samo co pascalowskie "iterator^"
  17.  
  18. template <class iter>
  19. iter stable_unique_1 ( iter first, iter last )
  20. {
  21.     unordered_set<int> temp; //zbiór użytych, pusty na poczatku
  22.     iter writer(first); //tym będziemy czytac kazdy element
  23.     iter reader(first); // tu bedziemy zapisywac tylko unikalne. poczatkowo oba wskazniki idą razem
  24.     while (reader!= last) { //czy to już koniec
  25.         if (temp.count(*reader)==0){  //element pokazywany przez reader nie istenije w temp
  26.             *writer=*reader; // kopiuj unikalny element na pierwsze należne miejsce
  27.             writer++; //przesuń owo miejsce
  28.             temp.insert(*reader); //dodajemy do zbioru już użytych
  29.         }
  30.         reader++;// kroczek
  31.     }
  32.     return writer; // zwracam iterator (wskaźnik) za ostatnim sensownym elementem,
  33.     //nie zmieniam wielkośći tablicy, tym sie zajme poziom wyzej,
  34.     //taka konwencja, patrz idiom remove-erase
  35. }
  36.  
  37.  
  38. template <class iter>
  39. iter stable_unique_2 ( iter first, iter last )
  40. {
  41.     set<int> temp; //zbiór użytych
  42.     iter writer(first);
  43.     iter reader(first);
  44.     while (reader!= last) { //czy to już koniec
  45.         if (temp.count(*reader)==0){  //element pokazywany przez reader nie istenije ww temp
  46.             *writer=*reader; // kopiuj unikalny element na pierwsze należne miejsce
  47.             writer++; //przesuń owo miejsce
  48.             temp.insert(*reader); //dodajemy do zbioru już użytych
  49.         }
  50.         reader++;// kroczek
  51.     }
  52.     return writer;
  53. }
  54.  
  55. template <class iter>
  56. iter stable_unique_3 ( iter first, iter last )
  57. {
  58.     iter writer(first);
  59.     iter reader(first);
  60.     while (reader!= last)  //czy to już koniec
  61.     {
  62.         if (count(first, writer, *reader)==0){  //elementu poszukiwany (wskazywany przez reader) nie ma
  63.                                                   //w już przetworzonym zakresie (od [first a przed writer)
  64.                                                 //lepiej byłoby użyć funkcji find:
  65.                                                 //find(first, writer, *reader)==writer) ale warunek trochę zaciemnia:)
  66.             *writer=*reader; // kopiuj unikalny element na pierwsze należne miejsce
  67.             writer++; //przesuń owo miejsce
  68.         }
  69.         reader++;// kroczek
  70.     }
  71.     return writer;
  72. }
  73.  
  74. template <class iter>
  75. iter stable_unique_4 ( iter first, iter last )
  76. {
  77.     unordered_set<int> temp(first, last); //zbiór nieużytych
  78.     iter writer(first);
  79.     iter reader(first);
  80.     while (reader!= last) { //czy to już koniec
  81.         if (temp.count(*reader)>0){  //element pokazywany przez reader istenije w temp
  82.             *writer=*reader; // kopiuj unikalny element na pierwsze należne miejsce
  83.             writer++; //przesuń owo miejsce
  84.             temp.erase(*reader); //dodajemy do zbioru już użytych
  85.         }
  86.         reader++;// kroczek
  87.     }
  88.     return writer;
  89. }
  90.  
  91.  
  92. template <class iter>
  93. iter unstable_unique ( iter first, iter last )
  94. {
  95.     sort(first, last);
  96.     return unique(first, last);
  97. }
  98.  
  99.  
  100. template <class iter>
  101. iter stable_unique_5 ( iter first, iter last )
  102. {
  103.     vector <int> sorted(first, last);
  104.     vector <uint8_t> visited(sorted.size(),0);
  105.     sort(sorted.begin(), sorted.end());
  106.  
  107.     iter writer(first);
  108.     iter reader(first);
  109.     while (reader!= last) { //czy to już koniec
  110.         auto it = lower_bound(sorted.begin(), sorted.end(),*reader);
  111.         if ( visited[ it-sorted.begin() ]==0  ){
  112.             *writer=*reader; // kopiuj unikalny element na pierwsze należne miejsce
  113.             writer++; //przesuń owo miejsce
  114.             visited[ it-sorted.begin() ] = 1;
  115.         }
  116.         reader++;// kroczek
  117.     }
  118.     return writer;
  119.  
  120. }
  121.  
  122.  
  123.  
  124.  
  125.  
  126. class stoper
  127. {
  128.     chrono::time_point<chrono::high_resolution_clock> a,b;
  129. public:
  130.     void start(){a = chrono::high_resolution_clock::now();}
  131.     void stop() {b = chrono::high_resolution_clock::now();}
  132.     double value()
  133.     {
  134.         chrono::duration<double> elapsed_seconds = b-a;
  135.         return elapsed_seconds.count();
  136.     }
  137. };
  138.  
  139.  
  140. template <typename F >
  141. void test (F f, string s,int size)
  142. {
  143.  
  144.     if( size == 100 ) {
  145.         vector<int> tab = {12,457,12,457,1,56,89,12,11,11,55,11,11,1,457};
  146.         tab.erase( f( tab.begin(),tab.end() ), tab.end()  );
  147.         cout<<s<<endl<<"poprawność:"<<endl; ;
  148.         for (auto a:tab)
  149.             cout<<a<<" ";
  150.         cout<<endl;
  151.     }
  152.  
  153.  
  154.     {
  155.         vector<int> tab ;
  156.  
  157.         random_device rd;
  158.         mt19937 gen(rd());
  159.  
  160.         tab.resize(size);
  161.         generate(tab.begin(), tab.end(), gen);
  162.         stoper st;   st.start();
  163.         tab.erase( f( tab.begin(),tab.end() ), tab.end()  );
  164.         st.stop();
  165.         cout<<size<<" zajelo "<<st.value()<<"s"<<endl;
  166.     }
  167.  
  168.     if( size == MAX_SIZE ) cout << endl;
  169.  
  170.  
  171. }
  172.  
  173. static unsigned int hash_mm( const int x , const unsigned int s2) {
  174.     const unsigned int xx = (unsigned int)x;
  175.     return ( (xx*67523u + 31237u) ^ (xx*78529u + 96285u) ) % s2;
  176. }
  177.  
  178. static bool exist_mm( const int x , int u[] , const unsigned int s2 ) {
  179.     unsigned int i = hash_mm( x , s2 );
  180.     while( u[i] != x && u[i] != 0 )
  181.         i = (i+1)%s2;
  182.     if( u[i] == 0 ) {
  183.         u[i] = x;
  184.         return false;
  185.     }
  186.     return true;
  187. }
  188.  
  189. static int uniq_mm( int t[], const int size ) {
  190.     const unsigned int s2 = (unsigned int)(size/2*5+2);
  191.     int *u = new int[s2];
  192.     memset( u , 0 , s2 * sizeof(int) );
  193.     int size2 = 0;
  194.     bool zero = 0;
  195.     for( int i=0 ; i<size ; i++ ) {
  196.         if( !zero && t[i] == 0 ) {
  197.             t[size2++] = t[i];
  198.             zero = true;
  199.         } else if( ! exist_mm( t[i] , u , s2) ) {
  200.             t[size2++] = t[i];
  201.         }
  202.     }
  203.  
  204.     delete[] u;
  205.     return size2;
  206. }
  207.  
  208. //template <class ForwardIterator, class Generator>
  209. //  void generate ( ForwardIterator first, ForwardIterator last, Generator gen ) !!! nie ma referencji na generator? jest referencja na rd w rd???
  210. //{
  211. //  while (first != last) {
  212. //    *first = gen();
  213. //    ++first;
  214. //  }
  215. //}
  216.  
  217.  
  218. static void generate( int t[], const int size , mt19937 gen )
  219. {
  220.   for( int i=0 ; i<size ; i++ )
  221.       t[i] = gen();
  222. }
  223.  
  224. static void test_mm( int size )
  225. {
  226.     if( size == 100 )
  227.     {
  228.         cout<<"samorobka"<<endl<<"poprawność:"<<endl; ;
  229.         int tab[] = {12,457,12,457,1,56,89,12,11,11,55,11,11,1,457};
  230.         int size2 = uniq_mm( tab , sizeof(tab)/sizeof(tab[0]) );
  231.  
  232.         for (int i=0 ; i<size2 ; i++ )
  233.             cout<<tab[i]<<" ";
  234.         cout<<endl;
  235.     }
  236.  
  237.     {
  238.         random_device rd;
  239.         mt19937 gen(rd());
  240.  
  241.         int *tab = new int[size];
  242.         generate( tab , size , gen );
  243.         stoper st;
  244.         st.start();
  245.         uniq_mm( tab , size );
  246.         st.stop();
  247.         cout<<size<<" zajelo "<<st.value()<<"s"<<endl;
  248.         delete[] tab;
  249.     }
  250.  
  251.     if( size == MAX_SIZE ) cout << endl;
  252. }
  253.  
  254.  
  255. int main()
  256. {
  257.  
  258.  
  259.     typedef vector<int>::iterator iter;
  260.     for( int s=100 ; s<=MAX_SIZE ; s*=10 )
  261.         test_mm( s );
  262.     for( int s=100 ; s<=MAX_SIZE/10 ; s*=10 )
  263.         test(  stable_unique_1<iter> ,"hashmapa budowana" , s );
  264.     for( int s=100 ; s<=MAX_SIZE/10 ; s*=10 )
  265.         test(  stable_unique_2<iter> , "zbior budowany" , s );
  266.     for( int s=100 ; s<=MAX_SIZE/10 ; s*=10 )
  267.         test(  stable_unique_4<iter> , "hashmapa usuwana " , s );
  268.     for( int s=100 ; s<=MAX_SIZE ; s*=10 )
  269.         test(  unstable_unique<iter> , "sortowanie "  , s);
  270.     for( int s=100 ; s<=MAX_SIZE/10 ; s*=10 )
  271.         test(  stable_unique_5<iter> , "sortowanie stab" , s );
  272.     return 0;
  273. }
Advertisement
Add Comment
Please, Sign In to add comment