C++ Eratosthenes实现的筛选
我正在尝试实现Eratosthenes筛的算法,但我不知道为什么这个程序在较大的程序中会崩溃。最初我使用的是C++ Eratosthenes实现的筛选,c++,sieve-of-eratosthenes,C++,Sieve Of Eratosthenes,我正在尝试实现Eratosthenes筛的算法,但我不知道为什么这个程序在较大的程序中会崩溃。最初我使用的是vector,但现在我使用动态内存分配来实现这一点 #include<iostream> #include<cmath> #include<cstdlib> using namespace std; unsigned isqrt(unsigned value) { return static_cast<unsigned>(sqrt(st
vector
,但现在我使用动态内存分配来实现这一点
#include<iostream>
#include<cmath>
#include<cstdlib>
using namespace std;
unsigned isqrt(unsigned value) {
return static_cast<unsigned>(sqrt(static_cast<float>(value)));
}
int main()
{
int t;
cin >> t;
long long * N;
long long * M;
long long n, m;
N = new long long[t];
M = new long long[t];
for(int i = 0; i < t ; i++){
cin >> M[i] >> N[i];
}
for(int i = 0; i < t ; i++){
n = N[i];
m = M[i];
bool * A;
A = new bool[n];
if(A == 0)
{
cout << "Memory cannot be allocated";
return 0;
}
for(int i=0;i < n;i++){
A[i]=true;
}
A[0] = false;
A[1] = false;
unsigned sqrt = isqrt(n);
for(int i = 2; i <= sqrt; i++)
{
if(A[i] == true){
for(int j = i*i; j <= n; j = j + i)
{
A[j] = false;
}
}
}
for(int i = m;i < n;i++)
{
if(A[i] == true )
cout << i << "\n";
}
delete[] A;
}
delete[] M;
delete[] N;
return 0;
}
#包括
#包括
#包括
使用名称空间std;
无符号isqrt(无符号值){
返回static_cast(sqrt(static_cast(value));
}
int main()
{
int t;
cin>>t;
长*N;
长*M;
长n,m;
N=新长[t];
M=新长[t];
for(int i=0;i>M[i]>>N[i];
}
for(int i=0;i coutfor(int j=i*i;jfor(int j=i*i;j在调试器中运行此命令,以确定崩溃的位置并从那里进行调试。在这一点上很可能很明显
您可以从IDE或命令行执行此操作。在后一种情况下,使用-g
编译并在程序(如gdb
)中运行。使用谷歌搜索类似“gdb备忘单”的内容开始。在调试器中运行此操作,以确定崩溃的位置并从那里进行调试。在这一点上很可能很明显
您可以从IDE或命令行执行此操作。在后一种情况下,使用-g
编译并在程序(如gdb
)中运行。使用谷歌搜索类似“gdb备忘单”的内容开始操作。如果n的大小足以导致内存分配错误,则程序将因此处错误的内存分配错误处理而崩溃
A = new bool[n];
if(A == 0)
{
cout << "Memory cannot be allocated";
return 0;
}
A=newbool[n];
如果(A==0)
{
cout如果n足够大,导致内存分配错误,程序将因此处错误的内存分配错误处理而崩溃
A = new bool[n];
if(A == 0)
{
cout << "Memory cannot be allocated";
return 0;
}
A=newbool[n];
如果(A==0)
{
如果你要用C++写埃拉托色尼的筛选器,如果你真的使用C++,那就不要把它当作C语言和汇编语言之间的某种疯狂交叉。
#include <vector>
#include <iostream>
unsigned long primes = 0;
int main() {
int number = 10000000;
std::vector<bool> sieve(number,false);
sieve[0] = sieve[1] = true;
for(int i = 2; i<number; i++) {
if(!sieve[i]) {
++primes;
for (int temp = 2*i; temp<number; temp += i)
sieve[temp] = true;
}
}
std::cout << "found: " << primes << " Primes\n";
return 0;
}
#包括
#包括
无符号长素数=0;
int main(){
整数=10000000;
标准::向量筛(数字,假);
筛[0]=筛[1]=真;
对于(int i=2;i)如果你要在C++中写埃拉托色尼的筛选器,如果你真的使用C++,那就不要把它当作C和汇编语言之间的某种疯狂交叉。
#include <vector>
#include <iostream>
unsigned long primes = 0;
int main() {
int number = 10000000;
std::vector<bool> sieve(number,false);
sieve[0] = sieve[1] = true;
for(int i = 2; i<number; i++) {
if(!sieve[i]) {
++primes;
for (int temp = 2*i; temp<number; temp += i)
sieve[temp] = true;
}
}
std::cout << "found: " << primes << " Primes\n";
return 0;
}
#包括
#包括
无符号长素数=0;
int main(){
整数=10000000;
标准::向量筛(数字,假);
筛[0]=筛[1]=真;
对于(int i=2;iI既看不到问题,也看不到问题/错误。程序崩溃-没有问题?unsigned sqrt=isqrt(n)
是错误的。重新计算每个输入对的筛选是多余的。应该只计算一次。您确实意识到,即使是高度优化的多线程,这是用C编写的Eratosthenes筛选版本,在现代台式计算机上筛选到10^16的素数也需要大约一个月的时间?这是代码它是开源的,所以你可以阅读它,但是你会发现它的功能非常复杂。你会发现你需要编写数百行代码(并学习很多技术和算法)还要注意的是,为了计算多个素数范围,正如您在这里的意图一样,不需要将整个素数范围筛选到最高素数索引,而只需筛选到最高素数索引的平方根,然后使用分段分页筛在所需范围内进行筛选,就像primesieve一样。我既看不到问题,也看不到问题/错误。程序崩溃-不是问题?unsigned sqrt=isqrt(n)
是错误的。重新计算每个输入对的筛选是多余的。应该只计算一次。您确实意识到,即使是高度优化的多线程,这是用C编写的Eratosthenes筛选版本,在现代台式计算机上筛选到10^16的素数也需要大约一个月的时间?这是代码它是开源的,所以你可以阅读它,但是你会发现它的功能非常复杂。你会发现你需要编写数百行代码(并学习很多技术和算法)还要注意的是,为了计算多个素数范围,正如您在这里的意图一样,不需要将整个素数范围筛选到最高素数索引,而只需筛选到最高素数索引的平方根,然后使用分段分页筛在所需范围内进行筛选,就像primesieve一样。但是为什么莫扎特和非法的访问内存会导致C++中的未定义行为。未定义行为的结果不一定是可预测的。这与java和Python之类的语言不同,它们几乎总是以可预测的和一致的方式崩溃。所以标准,THI。应该是prohibited@cf16如果你说无效的访问应该被困在某种程度上,你就失去了C++的一个好处——它不会浪费时间在每次访问之前检查索引。如果你需要这种手握,选择不同的语言,并希望它运行得慢些。@ MalksOM:你可以在C++中得到这种类型的指针。+例如,将std::vector
与at()一起使用会检查所有访问。但是为什么只有M和N的值更大,而不是小的值?@莫扎特非法访问内存会导致C++中的未定义行为。未定义行为的结果不一定是可预测的。这与java和Python语言不同,它们几乎总是在可预测的情况下崩溃。一致的方式。所以标准,这应该是prohibited@cf16如果你说无效访问应该被困在某种程度上,你就失去了C++的一个好处——它不浪费时间检查TH。