fork download
  1. #include <ctime>
  2. #include <algorithm>
  3. #include <random>
  4. #include <iostream>
  5. #include <set>
  6.  
  7. double boundedSumJoe(std::vector<int> x, int lower, int upper) {
  8.  
  9. int myMax = *std::max_element(x.begin(), x.end());
  10. int offSet = std::abs(*std::min_element(x.begin(), x.end())) + 1;
  11. unsigned long int myRange;
  12.  
  13. if (myMax > 0)
  14. myRange = myMax + offSet; // E.g. if myMax = 10 & myMin = -2, then myRange = 12
  15. else
  16. myRange = offSet;
  17.  
  18. offSet--;
  19.  
  20. std::vector<int> frequency(myRange, 0);
  21. std::vector<int> values(myRange, 0);
  22. std::vector<int>::iterator it, itEnd = x.end();
  23. int myIndex;
  24. double mySum = 0;
  25.  
  26. for (it = x.begin(); it < itEnd; it++) {
  27. myIndex = *it + offSet;
  28. frequency[myIndex]++;
  29. values[myIndex] = *it;
  30. }
  31.  
  32. int count = 0;
  33. bool firstHit = true;
  34.  
  35. for (std::size_t j = 0; j < myRange; j++) {
  36. if (frequency[j]) {
  37. if (count >= lower) {
  38. if (count <= upper) {
  39. firstHit = false;
  40. mySum += values[j] * frequency[j];
  41. } else {
  42. if ((count - upper) > 1) {
  43. int k = j - 1;
  44. while (!frequency[k]) {k--;}
  45. mySum -= (values[k] * (count - upper - 1));
  46. }
  47. break;
  48. }
  49. }
  50. count += frequency[j];
  51. if ((count - lower) >= 1 && firstHit) {
  52. firstHit = false;
  53. mySum += (values[j] * (count - lower));
  54. }
  55. }
  56. }
  57.  
  58. return mySum;
  59. }
  60.  
  61. double boundedSumBen(std::vector<int> x, int lower, int upper) {
  62. double mySum = 0;
  63. // First partition vector at larger bound
  64. std::nth_element(x.begin(), x.begin() + upper, x.end());
  65. // Now create partition of above at lower bound
  66. std::nth_element(x.begin(), x.begin() + lower, x.begin() + upper);
  67. std::vector<int>::iterator it, itEnd = x.begin() + upper;
  68. for (it = x.begin() + lower; it <= itEnd; it++)
  69. mySum += *it;
  70. return mySum;
  71. }
  72.  
  73. double boundedSumOP(std::vector<int> x, int lower, int upper) {
  74. double mySum = 0;
  75. std::sort(x.begin(), x.end());
  76. std::vector<int>::iterator it, itEnd = x.begin() + upper;
  77. for (it = x.begin() + lower; it <= itEnd; it++)
  78. mySum += *it;
  79. return mySum;
  80. }
  81.  
  82. int main() {
  83. std::vector<int> v(200001);
  84. std::random_device rd;
  85. std::mt19937 gen(rd());
  86. std::iota(v.begin(), v.end(), -100000);
  87. std::shuffle(v.begin(), v.end(), gen);
  88.  
  89. // random-sample without replacement
  90. std::vector<int> randVec(v.begin(), v.begin() + 100000);
  91. int val1, val2, val3;
  92. std::clock_t start_time, end_time;
  93.  
  94. start_time = clock();
  95. for (std::size_t i = 0; i < 100; i++)
  96. val1 = boundedSumBen(randVec, 49900, 50100);
  97. end_time = clock();
  98.  
  99. std::cout << "time taken on sample w/o rep std::nth_element : " <<
  100. end_time - start_time << std::endl;
  101.  
  102. start_time = clock();
  103. for (std::size_t i = 0; i < 100; i++)
  104. val2 = boundedSumJoe(randVec, 49900, 50100);
  105. end_time = clock();
  106.  
  107. std::cout << "time taken on sample w/o rep indexing method by Joe : " <<
  108. end_time - start_time << std::endl;
  109.  
  110. start_time = clock();
  111. for (std::size_t i = 0; i < 100; i++)
  112. val3 = boundedSumOP(randVec, 49900, 50100);
  113. end_time = clock();
  114.  
  115. std::cout << "time taken on sample w/o rep naive approach with std::sort : " <<
  116. end_time - start_time << std::endl;
  117.  
  118. std::cout << "All functions on sample w/o rep return the same value of : " <<
  119. val1 << ", " << val2 << ", and " << val3 << std::endl;
  120.  
  121.  
  122. /// Now we test a random sample with replacement
  123. std::uniform_int_distribution<int> distribution(-100000, 100000);
  124. for (std::size_t i = 0; i < 100000; i++)
  125. randVec[i] = distribution(gen);
  126.  
  127. start_time = clock();
  128. for (std::size_t i = 0; i < 100; i++)
  129. val1 = boundedSumBen(randVec, 9900, 10100);
  130. end_time = clock();
  131.  
  132. std::cout << "time taken on sample with rep std::nth_element : " <<
  133. end_time - start_time << std::endl;
  134.  
  135. start_time = clock();
  136. for (std::size_t i = 0; i < 100; i++)
  137. val2 = boundedSumJoe(randVec, 9900, 10100);
  138. end_time = clock();
  139.  
  140. std::cout << "time taken on sample with rep indexing method by Joe : " <<
  141. end_time - start_time << std::endl;
  142.  
  143. start_time = clock();
  144. for (std::size_t i = 0; i < 100; i++)
  145. val3 = boundedSumOP(randVec, 9900, 10100);
  146. end_time = clock();
  147.  
  148. std::cout << "time taken on sample with rep naive approach with std::sort : " <<
  149. end_time - start_time << std::endl;
  150.  
  151. std::cout << "All functions on sample with rep return the same value of : " <<
  152. val1 << ", " << val2 << ", and " << val3 << std::endl;
  153.  
  154. std::cout << "Number of unique elements in vector with replacement "
  155. << std::set<int>(randVec.begin(), randVec.end()).size()
  156. << std::endl;
  157.  
  158. return 0;
  159. }
  160.  
Success #stdin #stdout 1.53s 7820KB
stdin
Standard input is empty
stdout
time taken on sample w/o rep std::nth_element : 81165
time taken on sample w/o rep indexing method by Joe : 170489
time taken on sample w/o rep naive approach with std::sort : 504257
All functions on sample w/o rep return the same value of : 276, 276, and 276
time taken on sample with rep std::nth_element : 82159
time taken on sample with rep indexing method by Joe : 151076
time taken on sample with rep naive approach with std::sort : 508046
All functions on sample with rep return the same value of : -16071322, -16071322, and -16071322
Number of unique elements in vector with replacement 78658