代码编辑软件:VSCODE
语言:C++、cppStandard: c++17、编译器:mingw64-GCC
古希腊数学家Eratosthenes(276~194 BC)所提出的一种方法, 给出要筛数值的范围n,找出以内的素数。先用2去筛,即把2留下,把2的倍数剔除掉;再用下一个质数,也就是3筛,把3留下,把3的倍数剔除掉;接下去用下一个质数5筛,把5留下,把5的倍数剔除掉;不断重复下去。能够生成所有 ≤ N ≤N ≤N的素数表, 直到2004年才被改进。改进版本的核心思想是若 n ≤ N n≤N n≤N且n是合数,则n必有一不大于 N sqrt{N} N 的素因子。最佳筛法的伪码表根据伪码表示的提示,在实际编码中,既要考虑程序的正确性,又要考虑程序的计算开销和存储开销,我们有以下优化算法的启发:
#include <iostream>
#include <vector>
#include <cmath>
#include <ctime>
using namespace std;// 书上的最优化的Eratosthenes算法
vector<long> sieveofEratosthenes(long n) {clock_t start,end;start = clock();// 确认素数vector<bool> isPrime(n + 1, true); // 初始化所有数均为素数,直接标记2-n,索引从0开始,为n+1 long m = sqrt(n); // 只需要筛选到sqrt(n)即可 for (long i = 2; i <= m; i++) { // 从2开始,将它的倍数都标记为非素数 if (isPrime[i]) { // 首先确认是否是素数,再用素数筛倍数for (long j = i * i; j <= n; j += i) {isPrime[j] = false;}}}end = clock();cout<<"sieve of Eratosthenes timeclock is: "<<double(end-start)<<"ms"<<endl;// 记录素数vector<long> primes;for (long i = 2; i <= n; i++) {if (isPrime[i]) {primes.push_back(i); }}return primes;
}vector<long> easyEratosthenes(long n) {// 确认素数clock_t start,end;start = clock();vector<bool> isPrime(n + 1, true); // 初始化所有数均为素数,直接标记2-n,索引从0开始,为n+1 for (long i = 2; i <= n; i++) { // 从2开始,将它的倍数都标记为非素数 for (long j = i * 2; j <= n; j += i) {isPrime[j] = false;}}end = clock();cout<<"easyEratosthenes timeclock is: "<<double(end-start)<<"ms"<<endl;
}int main() {long n;cout << "input the n:" << endl;cin >> n;vector<long> primes = sieveofEratosthenes(n);easyEratosthenes(n);/*for (long prime : primes) {cout << prime <<" "<< endl; }return 0;*/
}
结果分析,时间上最优的筛法和最原始的筛法,在结果上是完全正确的且一致的,但是在计算速度上差距甚大,在10000000的时候差距接近1:5.5。但是由于代码为了便于编写使用了vector函数,若使用最简单的数组来做,运行速度和存储效率可能还对提升,但这不是这次实验的主要目的。
引入雅可比符号,正是因为计算勒让德符号时,需要把 n n n分解成标准分解式,这常常时很麻烦的,这也是运用勒让德符号进行计算时的缺点,避开这个缺点,就是引入雅可比符号,它的计算法则,容易由勒让德符号的性质推出。
分析,利用以上定理即可计算雅可比符号,这是柯召《数论讲义》上的定理,上述定理经过某些推导可产生更具体的结论,下面这套:
通过C++编写实现对雅可比符号的计算,然后验证雅可比符号计算的正确性,由于上述实验原理本质相同,在算术上的改进效果甚微,因此在本代码的编写中考虑到计算的特征,准备对雅可比符号的计算函数设计嵌套模式。
#include <iostream>
using namespace std; int jacobiSymbol(int a, int n) {if (a == 0) {return 0;}if (a == -1){if((n-1)%2) return 1;else return -1;}if (n == 1) {return 1;}if (a % 2 == 0) { //定理三应用int k=(n^2-1)%8;if (k%2 == 0) return jacobiSymbol(a/2,n);else return -jacobiSymbol(a/2, n);}if (a<n && n % 2 == 1 && a % 2 == 1) {int zf = ((a-1)*(n-1))/4; // 互反正负标识位if (zf%2) return jacobiSymbol(n, a);else return -jacobiSymbol(n,a);}if (a>n) { a = a % n; return jacobiSymbol(a, n);}
}int main() { int a, n; cout << "Enter the value of a: "; cin >> a; cout << "Enter the value of n which must be the odd integer: "; cin >> n; int result = jacobiSymbol(a, n); cout << "The Jacobi_symobol is "<<result<<endl;return 0;
}
结果表明,雅可比符号计算具有正确性
本文发布于:2024-01-28 03:27:39,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/17063836634455.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |