Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 带c+的素数+;,代码有什么问题,如何优化?_C++ - Fatal编程技术网

C++ 带c+的素数+;,代码有什么问题,如何优化?

C++ 带c+的素数+;,代码有什么问题,如何优化?,c++,C++,我试图解决这个问题,我需要以最快的方式找到介于1到3501之间的素数,因为时间限制可能不会超过1秒 我计算这些素数的方法是检查它们在平方根之前是否为素数,然后消除第一个素数的倍数[2,3,5,7],以提高算法的性能。然而,时间已经超过了 我的代码(采用1.560s作为提交系统的内部测试) #包括 #包括 #包括 #包括 #包括 #包括 使用名称空间std; 设立保监会; 设置素数; /*计算列表素数*/ 无效n_素数(整数qtd){ int a,flag=1,l_素数=1; 浮动n; 对于(in

我试图解决这个问题,我需要以最快的方式找到介于1到3501之间的素数,因为时间限制可能不会超过1秒

我计算这些素数的方法是检查它们在平方根之前是否为素数,然后消除第一个素数的倍数[2,3,5,7],以提高算法的性能。然而,时间已经超过了

我的代码(采用1.560s作为提交系统的内部测试)

#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
设立保监会;
设置素数;
/*计算列表素数*/
无效n_素数(整数qtd){
int a,flag=1,l_素数=1;
浮动n;
对于(int i=0;i7)
而(l|u素数%2==0 | l|u素数%3==0 | l|u素数%5==0 | l|u素数%7==0)l|u素数++;
n=sqrt(l_素数);
对于(a=2;a而言,最简单的方法是,以下是我的实现:

//return the seive of erstothenes
std::vector<int> generate_seive(const ulong & max) {
    std::vector<int> seive{2};
    std::vector<bool> not_prime(max+1);
    ulong current_prime = seive.back();
    bool done = false;
    while(!done){ 
        for (int i = 2; i * current_prime <= max;i++) {
            not_prime[i*current_prime]=true;
        }
        for (int j = current_prime+1;true;j++) {
            if (not_prime[j] == false) {
                if( j >= max) {
                    done = true;
                    break;
                }
                else {
                    seive.push_back(j);
                    current_prime = j;
                    break;
                }
            }
        }
    }
    return seive;
}

有一种更好的求素数的算法。你听说过吗


此外,您在代码中使用了大量STL(即集合)和余数操作。这只会降低程序的速度。

一些基本建议,然后是一个基本(尽管未经测试)答案

建议:如果您有一个非常有限的资源,请利用其他资源。在这种情况下,由于时间有限,会占用大量空间。不要动态分配任何内存,而是将其全部设置为固定长度数组

我的方法是简单地使用一个布尔数组,并对其应用Aristophanes筛:

void findPrimes(int cap) { // set to void for now, since I don't know your return type
    bool[] possibilities = new bool[cap + 1]; // has to be dynamic so that you can scale for any top
    possibilities[0] = false;
    possibilities[1] = false;
    int found = 0;

    for (int i = 2; i < cap; ) {
        ++found;
        for (int j = i + i; j < cap; j += i) {
            possibilities[j] = false;
        }
        do {
            ++i;
        } while (!possibilities[i]);
    }

    // at this point, found says how many you've found, and everything in possibilities that is true is a factor.  Just return it however you need.
void findpremes(int cap){//暂时设置为void,因为我不知道您的返回类型
bool[]posabilities=new bool[cap+1];//必须是动态的,以便可以缩放任何顶部
可能性[0]=假;
可能性[1]=错误;
int=0;
对于(int i=2;i

我看到aaronman用筛子的想法击败了我。我的是一个稍微不同的实现(更像原来的筛子,只使用加法),并使用更少的动态内存,因此我仍在提交它。

通过预先排除偶数,您可以获得相当好的加速,只需将增量更改为
I+=2
,并确保在结果数组中不忽略2。您甚至可能会考虑预先排除3的倍数,但这会开始变脏nes:

for(long i = 1; i < qtd; i += 6) {
    //check if i is prime
    //check if i+4 is prime
}
for(长i=1;i

这应该足以让您低于限制。

正如其他人所建议的那样,Eratosthenes筛子是正确的方法。但是我在这里看到的实现非常复杂。筛子非常容易实现。例如:

std::vector<int> get_primes(uint max) {
  std::vector<int> primes;
  std::vector<bool> is_composite(max+1,false);
  for (uint i = 2; i <= max; ++i) {
    if (!is_composite[i]) {
      primes.push_back(i);
      for (uint j = i+i; j <= max; j += i) {
        is_composite[j] = true;
      }
    }
  }
  return primes;
}
std::向量get_素数(uint max){
向量素数;
std::向量是_复合的(max+1,false);

对于(uint i=2;i,代码中有两个大的技术性能损耗:

  • 将素数插入向量。每当向量超过其分配的大小时,它将获得一个新的、更大的缓冲区,复制所有内容并删除旧的缓冲区。
    new
    在性能方面非常昂贵,甚至比所涉及的复制更昂贵。您可以通过告诉向量
    reserve()
    足够的空间

  • 在内部循环中使用
    sqrt()
    。这也是一个缓慢的函数,取而代之的是平方素数(在现代硬件上只需要一个周期),它会更快


  • 只需使用它,这是ErasoStes筛选器的一个优化版本。但是对于你的小范围,很可能速度差只有三分之一。BTW如果你喜欢这样的问题,你应该真的尝试STL没有什么问题,在大多数情况下使用它会大大提高你的代码是什么意思?“模块操作”?你知道什么[漂亮]结构隐藏在集合后面?这里的问题是它完全不相关——你可以使用一个简单的数组。STL是否改进了你的代码是另一个话题。当然它对你有很大帮助。但是,如果你想要最快的解决方案,最好自己实现所有内容。@DavidBrown我指的是余数(或模数)谢谢,我会纠正它。@亚森我并没有说你应该使用一套,但是STL数据结构一般不会减慢你的代码的任何数量,任何C++专家都会告诉你总是喜欢C标准样式的标准库中的东西,或者你可能会想到在T之前预先排除每个素数的倍数。他是你正在考虑的一个…但是你会是Eratosthenes.:-p你的代码实现至少排除了3和19。不,筛选意味着必须从字段中标记出数字并始终检查标记,或者压缩一个数字数组,这更慢。我认为,他的基本方法很好,可以轻松改进已充分禁用。@ScottMermelstein如果您记得事先将其添加到结果数组中,则不需要。19=3*6+1,这已被选中。这很好,但没有实现is_compositeabout 1:重新分配和复制的次数太少,以至于与最终性能完全无关(如毫秒)。使用
    reserve()
    还是有道理的,只是说它对这里的慢度没有真正的帮助。有人想告诉我为什么-1?不是我,但你确实完全拼写了Eratostheneswrong@aaronman责怪谷歌!:->如果你输入“ar筛选”,它会自动将其填写到“aristophanes”并链接到
    for(long i = 1; i < qtd; i += 6) {
        //check if i is prime
        //check if i+4 is prime
    }
    
    std::vector<int> get_primes(uint max) {
      std::vector<int> primes;
      std::vector<bool> is_composite(max+1,false);
      for (uint i = 2; i <= max; ++i) {
        if (!is_composite[i]) {
          primes.push_back(i);
          for (uint j = i+i; j <= max; j += i) {
            is_composite[j] = true;
          }
        }
      }
      return primes;
    }