【问题标题】:Prime generator using a huge array in C在 C 中使用巨大数组的 Prime 生成器
【发布时间】:2017-06-06 00:10:51
【问题描述】:

我正在尝试使用数组制作素数生成器。我从一维数组开始,但我的计算机上的最大限制是 250000。所以我想也许我应该制作一个二维或更多数组,以便在达到此限制后转到下一行,以避免我的 PC 出现问题。但我不知道该怎么做。欢迎任何帮助。

#include<stdio.h>
#include<math.h>
#include<stdbool.h>
#include<time.h>
#define LIMIT 250000ul

//prime number generator using arrays 

void prime_generator(){

    unsigned long long n; 
    printf("How many primes do you want generated : "); 
    scanf("%llu", &n);

    unsigned long long p[LIMIT];  
    unsigned long long i, j=2; 
    unsigned long long num; 
    bool isPrime; 

    unsigned long long primes_per_line, space_column; 
    printf("How many primes do you want displayed per line? : "); 
    scanf("%llu", &primes_per_line); 
    printf("Enter space : "); 
    scanf("%llu", &space_column); 

    p[0]=2, p[1]=3;//first two primes
    unsigned long long count = 2; 

    clock_t begin = clock();   
    for(num = 5;count < n; num=num+2){//only test for odd number 
        isPrime = true; 
        for(i = 1;i < j && p[i] <= sqrt(num) ;i++){
            if(num%p[i]==0){
                isPrime = false;  
                break;//break out of i loop 
            }
        }
        if(isPrime == true){
            ++count; 
            p[j] = num; //new prime found 
            ++j; 
        }
    }
    clock_t end = clock(); 
    double time_spent = (double) (end-begin)/CLOCKS_PER_SEC; 

    for(i = 0; i < n; i++){
        if(i!=0 && i % primes_per_line == 0) printf("\n"); 
        printf("%*llu", space_column, p[i]); 
    }

    printf("\nCrunching time is : %.12f", time_spent);
}

int main(void){
    prime_generator(); 
    return 0; 
}

【问题讨论】:

  • 更改数组的维度不会增加您可用的内存量。
  • 二维数组不会比一维数组占用更少的内存。考虑改用动态内存 - 即,调用malloc。更好的是,改进您的算法,使其不需要那么多内存。
  • 如果您的编译器没有“看到内部”sqrt(num),那么该函数将被重复调用 - 不必要。建议unsigned long long limit = llrint(sqrt(num)); for(i = 1;i &lt; j &amp;&amp; p[i] &lt;= limit;i++){ ...

标签: c arrays memory


【解决方案1】:

您的unsigned long long p[LIMIT]; 是您的prime_generator 函数内部的一个本地 变量(带有automatic storage duration),因此它位于call stack(通常限制为1 或几兆字节) )。将其声明为 static 或将其设为 global 变量(在这两种情况下,它都会获得 static storage duration)。然后它可能会更大,但您的 prime_generator 将不再是 re-entrant(但在您的情况下,您不在乎)。

将数组声明为多维不会提高其内存大小(因此不会解决声明的变量local的调用帧大小过大的问题。

更好的是,使用C dynamic memory allocation,即calloc(不要忘记测试它是否失败,当它返回NULL时使用perror然后exit)和free;当心memory leaksvalgrind 之类的工具可能会有所帮助。使用calloc(或malloc)之后,您的virtual address space 将增长,并受到机器和系统资源(可能是千兆字节)的限制。

避免buffer overflows。见this

还可以阅读 prime numbersprimality tests 上的维基页面。还有更高效的算法。

您应该能够计算一百万个素数(以 15485761 结尾 15485773 15485783 15485801 15485807 15485837 15485843 15485849 15485857 15485863) 最多几秒钟(可能不到半秒钟)。

【讨论】:

    猜你喜欢
    • 2010-11-01
    • 2020-12-16
    • 2016-03-05
    • 1970-01-01
    • 1970-01-01
    • 2015-02-25
    • 1970-01-01
    • 2017-07-08
    • 2014-01-05
    相关资源
    最近更新 更多