fork download
  1. #include <algorithm>
  2. #include <cassert>
  3. #include <chrono>
  4. #include <iostream>
  5. #include <set>
  6. #include <unordered_set>
  7. #include <vector>
  8.  
  9. template <typename T>
  10. void reserve(std::set<T>&, size_t) {}
  11. template <typename T>
  12. void reserve(std::unordered_set<T>& s, size_t n) { s.reserve(n); }
  13.  
  14. template<bool Sorted, class Rng>
  15. std::vector<unsigned int> draw_select(unsigned int k, unsigned int n, Rng& rng)
  16. {
  17. std::vector<unsigned> v;
  18. if (6*k > n) { // Experimentell bestimmt!
  19. v.reserve(n); for (unsigned i=0; i<n; ++i) v.push_back(i); // iota_n
  20. for (unsigned i=k; i<n; ++i) {
  21. auto del=std::uniform_int_distribution<unsigned>(0, v.size())(rng);
  22. std::swap(v[del], v.back());
  23. v.pop_back();
  24. }
  25. if (Sorted) std::sort(v.begin(), v.end());
  26. } else {
  27. typename std::conditional<Sorted, std::set<unsigned>, std::unordered_set<unsigned> >::type set;
  28. reserve(set, k);
  29. std::uniform_int_distribution<unsigned> dis(0, n-1);
  30. while (set.size() != k)
  31. set.insert(dis(rng));
  32. v.reserve(n); v.assign(set.begin(), set.end());
  33. }
  34. return v;
  35. }
  36.  
  37. template<class Rng>
  38. std::vector<unsigned int> drawUniqueSubset(unsigned int k, unsigned int n, Rng& rng)
  39. {
  40. return draw_select<true>(k, n, rng);
  41. }
  42.  
  43. template<class Rng>
  44. std::vector<unsigned int> drawUniqueSubsetOrdered(unsigned int k, unsigned int n, Rng& rng)
  45. {
  46. return draw_select<false>(k, n, rng);
  47. }
  48.  
  49. template <typename C, typename F>
  50. void measure(C& c, const char *msg, F&& f)
  51. {
  52. auto start = c.now();
  53. std::forward<F>(f)();
  54. auto end = c.now();
  55. std::cout << msg << ": "
  56. << std::chrono::duration_cast<std::chrono::milliseconds>(end-start).count()
  57. << "ms\n";
  58. }
  59.  
  60. int main()
  61. {
  62. std::minstd_rand rng;
  63. const unsigned n=1000000;
  64. std::chrono::high_resolution_clock c;
  65.  
  66. for (unsigned k=0; k<=100; k+=5) {
  67. std::cout << k << "%\n";
  68. std::vector<unsigned> v;
  69.  
  70. measure(c, " unsorted: ", [&](){v=drawUniqueSubset(k*n/100, n, rng);});
  71. assert(v.size() == k*n/100);
  72. std::sort(v.begin(), v.end());
  73. assert(std::unique(v.begin(), v.end())==v.end());
  74. for (auto i : v) assert(i < n);
  75. std::vector<unsigned>().swap(v);
  76. measure(c, " sorted: ", [&](){v=drawUniqueSubset(k*n/100, n, rng);});
  77. assert(v.size() == k*n/100);
  78. assert(std::is_sorted(v.begin(), v.end()));
  79. assert(std::unique(v.begin(), v.end())==v.end());
  80. for (auto i : v) assert(i < n);
  81. std::vector<unsigned>().swap(v);
  82. }
  83. }
Success #stdin #stdout 4.28s 6912KB
stdin
Standard input is empty
stdout
0%
  unsorted: : 0ms
  sorted:   : 0ms
5%
  unsorted: : 24ms
  sorted:   : 26ms
10%
  unsorted: : 61ms
  sorted:   : 65ms
15%
  unsorted: : 131ms
  sorted:   : 128ms
20%
  unsorted: : 103ms
  sorted:   : 89ms
25%
  unsorted: : 90ms
  sorted:   : 94ms
30%
  unsorted: : 92ms
  sorted:   : 92ms
35%
  unsorted: : 97ms
  sorted:   : 97ms
40%
  unsorted: : 101ms
  sorted:   : 96ms
45%
  unsorted: : 109ms
  sorted:   : 97ms
50%
  unsorted: : 99ms
  sorted:   : 103ms
55%
  unsorted: : 101ms
  sorted:   : 104ms
60%
  unsorted: : 107ms
  sorted:   : 109ms
65%
  unsorted: : 106ms
  sorted:   : 117ms
70%
  unsorted: : 113ms
  sorted:   : 119ms
75%
  unsorted: : 112ms
  sorted:   : 115ms
80%
  unsorted: : 118ms
  sorted:   : 113ms
85%
  unsorted: : 116ms
  sorted:   : 116ms
90%
  unsorted: : 113ms
  sorted:   : 118ms
95%
  unsorted: : 112ms
  sorted:   : 113ms
100%
  unsorted: : 35ms
  sorted:   : 42ms