Advertisement
Guest User

Untitled

a guest
Aug 21st, 2019
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.00 KB | None | 0 0
  1. class PrimeGenerator {
  2. public:
  3. PrimeGenerator() = default;
  4. ~PrimeGenerator() = default;
  5.  
  6. static std::vector<unsigned> generatePrimes(unsigned maxValue);
  7.  
  8. private:
  9. static void uncrossIntegersUpTo(unsigned maxValue);
  10. static void crossOutMultiples();
  11. static unsigned determineIterationLimit();
  12. static void crossOutMultiplesOf(unsigned i);
  13. static bool notCrossed(unsigned i);
  14. static void putUncrossedIntegersIntoResult();
  15. static unsigned numberOfUncrossedIntegers();
  16.  
  17. static std::vector<bool> crossedOut;
  18. static std::vector<unsigned> result;
  19. };
  20.  
  21. std::vector<bool> PrimeGenerator::crossedOut;
  22. std::vector<unsigned> PrimeGenerator::result;
  23.  
  24. std::vector<unsigned> PrimeGenerator::generatePrimes(unsigned maxValue)
  25. {
  26. if (maxValue < 2)
  27. return {};
  28.  
  29. uncrossIntegersUpTo(maxValue);
  30. crossOutMultiples();
  31. putUncrossedIntegersIntoResult();
  32. return result;
  33. }
  34.  
  35. void PrimeGenerator::uncrossIntegersUpTo(unsigned maxValue)
  36. {
  37. crossedOut = std::vector<bool>(maxValue + 1, false);
  38. crossedOut[0] = true;
  39. crossedOut[1] = true;
  40. }
  41.  
  42. void PrimeGenerator::crossOutMultiples()
  43. {
  44. unsigned limit = determineIterationLimit();
  45. for (size_t i = 2; i <= limit; ++i)
  46. {
  47. if (notCrossed(i))
  48. crossOutMultiplesOf(i);
  49. }
  50. }
  51.  
  52. unsigned PrimeGenerator::determineIterationLimit()
  53. {
  54. // Every multiple in the array has a prime factor that
  55. // is less than or equal to the root of the array size,
  56. // so we don't have to cross out multiples of numbers
  57. // larger than that root.
  58. double iterationLimit = std::sqrt(crossedOut.size());
  59. return static_cast<unsigned>(iterationLimit);
  60. }
  61.  
  62. void PrimeGenerator::crossOutMultiplesOf(unsigned i)
  63. {
  64. for (size_t multiple = 2 * i; multiple < crossedOut.size(); multiple += i)
  65. {
  66. crossedOut[multiple] = true;
  67. }
  68. }
  69.  
  70. bool PrimeGenerator::notCrossed(unsigned i)
  71. {
  72. return !crossedOut[i];
  73. }
  74.  
  75. void PrimeGenerator::putUncrossedIntegersIntoResult()
  76. {
  77. result = std::vector<unsigned>(numberOfUncrossedIntegers());
  78. size_t j = 0;
  79. for (size_t i = 2; i < crossedOut.size(); ++i)
  80. {
  81. if (notCrossed(i))
  82. result[j++] = i;
  83. }
  84. }
  85.  
  86. unsigned PrimeGenerator::numberOfUncrossedIntegers()
  87. {
  88. unsigned count = 0;
  89. for (size_t i = 2; i < crossedOut.size(); ++i)
  90. {
  91. if (notCrossed(i))
  92. count++;
  93. }
  94.  
  95. return count;
  96. }
  97.  
  98. namespace PrimeGenerator
  99. {
  100. std::vector<unsigned> generatePrimes(unsigned maxValue);
  101. }
  102.  
  103. namespace {
  104.  
  105. std::vector<bool> uncrossIntegersUpTo(int maxValue)
  106. {
  107. std::vector<bool> crossedOut(maxValue + 1, false);
  108. crossedOut[0] = true;
  109. crossedOut[1] = true;
  110.  
  111. return crossedOut;
  112. }
  113.  
  114. unsigned determineIterationLimit(size_t size)
  115. {
  116. // Every multiple in the array has a prime factor that
  117. // is less than or equal to the root of the array size,
  118. // so we don't have to cross out multiples of numbers
  119. // larger than that root.
  120. double iterationLimit = std::sqrt(size);
  121. return static_cast<unsigned>(iterationLimit);
  122. }
  123.  
  124. void crossOutMultiplesOf(unsigned i, std::vector<bool>& crossedOut)
  125. {
  126. for (size_t multiple = 2 * i; multiple < crossedOut.size(); multiple += i)
  127. {
  128. crossedOut[multiple] = true;
  129. }
  130. }
  131.  
  132. void crossOutMultiples(std::vector<bool>& crossedOut)
  133. {
  134. unsigned limit = determineIterationLimit(crossedOut.size());
  135. for (size_t i = 2; i <= limit; ++i)
  136. {
  137. if (!crossedOut[i])
  138. crossOutMultiplesOf(i, crossedOut);
  139. }
  140. }
  141.  
  142. std::vector<unsigned> putUncrossedIntegersIntoResult(const std::vector<bool>& crossedOut)
  143. {
  144. std::vector<unsigned> result;
  145. for (size_t i = 2; i < crossedOut.size(); ++i)
  146. {
  147. if (!crossedOut[i])
  148. result.push_back(i);
  149. }
  150.  
  151. return result;
  152. }
  153.  
  154. }
  155.  
  156. namespace PrimeGenerator {
  157.  
  158. std::vector<unsigned> generatePrimes(unsigned maxValue)
  159. {
  160. if (maxValue < 2)
  161. return {};
  162.  
  163. auto crossedOut = uncrossIntegersUpTo(maxValue);
  164. crossOutMultiples(crossedOut);
  165. return putUncrossedIntegersIntoResult(crossedOut);
  166. }
  167.  
  168. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement