写作业写的,放这备用
C语言描述
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#include<stdbool.h>
#include<math.h>
#define NUM 10000
//暴力解法
void prime(unsigned n) {
for (size_t i = 2; i < n; i++)
if (!(n % i)) return;
//printf("%ud ", n);
}
void force(void) {
for (size_t i = 2; i <= NUM; prime(i++));
}
//暴力解法-优化
void prime_opt(unsigned n) {
if (!(n % 2) && (n != 2)) return;
for (size_t i = 3; i * i <= n; i += 2)
if (!(n % i)) return;
//printf("%ud ", n);
}
void force_opt(void) {
for (size_t i = 2; i <= NUM; prime_opt(i++));
}
//埃拉托斯特尼筛法
void eratosthenes(void) {
bool* prime = (bool*)calloc((NUM + 5), sizeof(bool));
memset(prime + 2, true, NUM + 3);
for (size_t i = 2; i <= NUM; i++)
if (prime[i])
for (size_t mutiple = 2; i * mutiple <= NUM; prime[i * mutiple++] = false);
/*for (size_t i = 0; i <= NUM; i++)
if (prime[i])
printf("%ud ", n);*/
if (prime != NULL) {
free(prime);
prime = NULL;
}
}
//埃拉托斯特尼筛法-优化
void eratosthenes_opt(void) {
bool* prime = (bool*)calloc((NUM + 5), sizeof(bool));
memset(prime + 2, true, NUM + 3);
unsigned tmp = sqrt(NUM);
for (size_t i = 2; i <= tmp; i++)
if (prime[i])
for (size_t mutiple = i * i; mutiple <= NUM; prime[mutiple] = false, mutiple += i);
/*for (size_t i = 0; i <= NUM; i++)
if (prime[i])
printf("%ud ", n);*/
if (prime != NULL) {
free(prime);
prime = NULL;
}
}
//欧拉筛法(线性筛法)
void euler(void) {
size_t t = 0;
size_t* f = (size_t*)calloc((NUM + 5), sizeof(size_t));
bool* prime = (bool*)calloc((NUM + 5), sizeof(bool));
memset(prime + 2, true, NUM + 3);
for (size_t i = 2; i <= NUM; i++) {
if (prime[i]) f[++t] = i;
for (size_t motiple = 1; motiple <= t && i * f[motiple] <= NUM; motiple++) {
prime[i * f[motiple]] = false;
if (!(i % f[motiple]))break;
}
}
/*for (size_t i = 0; i <= NUM; i++)
if (prime[i])
printf("%ud ", n);*/
if (f != NULL) {
free(f);
f = NULL;
}
if (prime != NULL) {
free(prime);
prime = NULL;
}
}
void Run_Time(void (*func)(void)) {
LARGE_INTEGER nFreq;
LARGE_INTEGER nBegin;
LARGE_INTEGER nEnd;
QueryPerformanceFrequency(&nFreq);
QueryPerformanceCounter(&nBegin);
func();
QueryPerformanceCounter(&nEnd);
auto time = (double)(nEnd.QuadPart - nBegin.QuadPart) / (double)nFreq.QuadPart;
printf("\nRun time:%g\n", time);
}
#define RT(FUN) Run_Time(std::bind(&Solution::FUN, s))
int main(int argc, char* argv[])
{
printf("Violence solution:");
Run_Time(force);
printf("Violence solution - Optimized Edition:");
Run_Time(force_opt);
printf("sieve of Eratosthenes:");
Run_Time(eratosthenes);
printf("sieve of Eratosthenes - Optimized Edition:");
Run_Time(eratosthenes_opt);
printf("sieve of Euler:");
Run_Time(euler);
return 0;
}
C++描述
//C++描述
#include<iostream>
#include<Windows.h>
#include<vector>
#include<algorithm>
#include<functional>
constexpr auto NUM = 10000;
class Solution {
unsigned num;
public:
Solution(unsigned n) :num(n) {}
//暴力解法
void force(void) {
for (size_t i = 2; i <= num;
[=](unsigned n) {
for (size_t i = 2; i < n; i++)
if (!(n % i)) return;
//std::cout << n << ' ';
}(i++)
);
}
//暴力解法-优化
void force_opt(void) {
for (size_t i = 2; i <= num;
[=](unsigned n) {
if (!(n % 2) && (n != 2)) return;
for (size_t i = 3; i * i <= n; i += 2)
if (!(n % i)) return;
//std::cout << n << ' ';
}(i++)
);
}
//埃拉托斯特尼筛法
void eratosthenes(void) {
bool* prime = new bool[num + 5]();
memset(prime + 2, true, num + 3);
for (size_t i = 2; i <= num; i++)
if (prime[i])
for (decltype(i) mutiple = 2; i * mutiple <= num; prime[i * mutiple++] = false);
/*for (size_t i = 0; i <= num; i++)
if (prime[i])
std::cout << i << ' ';*/
if (prime != nullptr) {
delete[]prime;
prime = nullptr;
}
}
//埃拉托斯特尼筛法-优化
void eratosthenes_opt(void) {
bool* prime = new bool[num + 5]();
memset(prime + 2, true, num + 3);
auto tmp = sqrt(num);
for (size_t i = 2; i <= tmp; i++)
if (prime[i])
for (decltype(i) mutiple = i * i; mutiple <= num; prime[mutiple] = false, mutiple += i);
/*for (size_t i = 0; i <= num; i++)
if (prime[i])
std::cout << i << ' ';*/
if (prime != nullptr) {
delete[]prime;
prime = nullptr;
}
}
//欧拉筛法(线性筛法)
void euler(void) {
size_t t{};
size_t* f = new size_t[num + 5]();
bool* prime = new bool[num + 5]();
memset(prime + 2, true, num + 3);
for (size_t i = 2; i <= num; i++) {
if (prime[i]) f[++t] = i;
for (size_t motiple = 1; motiple <= t && i * f[motiple] <= num; motiple++) {
prime[i * f[motiple]] = false;
if (!(i % f[motiple]))break;
}
}
/*for (size_t i = 0; i <= num; i++)
if (prime[i])
std::cout << i << ' ';*/
if (f != nullptr) {
delete[]f;
f = nullptr;
}
if (prime != nullptr) {
delete[]prime;
prime = nullptr;
}
}
};
void Run_Time(std::function<void(void)> func) {
LARGE_INTEGER nFreq;
LARGE_INTEGER nBegin;
LARGE_INTEGER nEnd;
QueryPerformanceFrequency(&nFreq);
QueryPerformanceCounter(&nBegin);
func();
QueryPerformanceCounter(&nEnd);
auto time = (double)(nEnd.QuadPart - nBegin.QuadPart) / (double)nFreq.QuadPart;
std::cout << "Run time:" << time << std::endl;
}
#define RT(FUN) Run_Time(std::bind(&Solution::FUN, s))
int main(int argc, char* argv[])
{
Solution s(NUM);
std::cout << "Violence solution:";
RT(force);
std::cout << "Violence solution - Optimized Edition:";
RT(force_opt);
std::cout << "sieve of Eratosthenes:";
RT(eratosthenes);
std::cout << "sieve of Eratosthenes - Optimized Edition:";
RT(eratosthenes_opt);
std::cout << "sieve of Euler:";
RT(euler);
return 0;
}
总结
寻找素数是算法最常见的基础题之一,以上几种则是这之中最基础的两种算法(试除法与埃氏筛),除此之外还有很多更快更好的算法此处不加赘述了。
在写实现的时候用了一些C++里花里胡哨的写法,顺便温习了一下function的用法。统计时间这里用的是Windows.h中的QueryPerformanceFrequency…STL中貌似也提供有很棒的计时库但是我没有用