C++ 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

我正在尝试实现Eratosthenes筛的算法,但我不知道为什么这个程序在较大的程序中会崩溃。最初我使用的是
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;icout
for(int j=i*i;j
for(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。