【问题标题】:Summation of nth prime第 n 个素数的总和
【发布时间】:2013-08-29 19:17:27
【问题描述】:

我正在编写一个查找素数总和的程序。它必须使用重定向输入。我已经编写了它,以便它找到输入的最大数字,然后将其用作第 n 个素数。然后它使用第 n 个素数来设置数组的大小。它一直有效,直到我尝试打印总和。我不知道为什么我在所有地方都出现了段错误。我想我已经用 malloc 正确分配了数组。为什么在我使用数组时不会在 printf 上发生故障?也欢迎对我的代码提出任何建议。

编辑 使用 2000 表格 1 到 2000 的测试输入并且它可以工作,但是 10000 表格 1 到 10000 崩溃的完整测试文件仍在寻找原因。我猜我没有分配足够的空间

编辑 我的问题是在我的筛子中,我没有使用 sqrt(nthprime),所以它找到了更多的素数,然后数组可以容纳

#include <stdio.h>
#include <stdlib.h>
#include <math.h>


int nprime (int max);
void sieve_sum ( int *primes, int nthprime, int tests,int *input);

int main(void)
{
    int i=0;
    int max=0; //largest input
    int tests; //number of tests
    int nthprime; //estimated nth prime
    int *primes; //array of primes
    int *input; // numbers to put in to P(n), where p(n) is the summation of primes

    scanf("%d",&tests); //gets number of tests
    input = malloc(sizeof(int)*tests);

    //test values
    for(i=0; i<=tests-1; i++)
        scanf("%d",&input[i]);

    //finds max test value
    i=0;
    for (i = 0; i < tests; i++ )
    {
        if ( input[i] > max-1 )
            max = input[i];
    }

    // calls nprime places value in n
    nthprime = nprime(max);
    primes = malloc(sizeof(int)*nthprime);

    // calls sieve_sum
    sieve_sum( primes, nthprime, tests, input);

    //free memory
    free(input);
    free(primes);
    return 0;
}

//finds Primes and their sum
void sieve_sum ( int *primes, int nthprime, int tests,int *input)
{
    int i;
    int j;

    //fills in arrays with 1's
    for(i=2; i<=nthprime; i++)
        primes[i] = 1;

    //replaces non primes with 0's
    i=0;
    for(i=2; i<=sqrt(nthprime); i++)
    {
        if(primes[i] == 1)
        {
            for(j=i; (i*j)<=(nthprime); j++)
                   primes[(i*j)] = 0;
        }
    }

    //rewrites array with only primes
    j=1;
    i=0;
    for(i=2; i<=nthprime; i++)
    {
        if(primes[i] == 1)
        {
            primes[j] = i;
            j++;
        }
    }

    //sums
    i=0;
    for ( i=1; i<=tests; i++ )
    {
        int sum=0;//sum of primes

        j=0;
        for(j=1; j<=input[i-1]; j++)
        {
                sum = primes[j] + sum;
        }

        printf("%d\n", sum );
    }
    return 0;
}

//finds the Nth number prime
int nprime (int max)
{
    //aproximization of pi(n) (the nth prime) times 2 ensures correct allocation of memory
    max = ceil( max*((log (max)) + log ((log (max)))))*2;
    return (max);
}

示例输入文件:

20
1
2
3
4
5
6
7
8
9
10
10
9
8
7
6
5
4
3
2
1

示例输出应该是:

2 
5 
10 
17 
28 
41 
58 
77 
100
129
129
100
77
58
41
28
17
10
5
2

【问题讨论】:

  • 这在几个层面上是错误的 - 我什至不知道从哪里开始。
  • 编译所有警告和调试信息(Linux 上的gcc -Wall -g)并在没有编译警告时使用调试器(gdb)。
  • 也许从阅读 malloc 的手册开始:manpagez.com/man/3/malloc(提示:malloc 期望分配的字节数作为参数。你可能缺少一个`* sizeof(int)`)
  • 另外,对于您的第 n 个素数函数,选择您的变量为 intdouble 并坚持使用它。到处都有隐式转换。
  • 请发布您正在使用的重定向输入。

标签: c arrays


【解决方案1】:

好的,所以我会尝试一下,不用说太多,因为它看起来可能是一个家庭作业问题。

我最好的猜测是,很多人甚至都不愿查看您的代码,因为对于他们的耐心水平来说,这有点太混乱了。这不是不可挽回的,但如果它相当干净,您可能会得到更好的响应。

因此,首先,对您的代码进行一些关键的 cmets 来帮助您清理它:它的注释不够充分,无法在任何级别明确您的意图,包括程序的总体目的是什么;它以非常规的方式不一致地缩进和间隔;并且您对变量名的选择还有一些不足之处,而变量声明中没有 cmets 会加剧这种情况。

你应该用类似的东西编译这段代码(假设你的源文件名为sumprimes.c):

gcc -std=c99 -pedantic -Wall -Wextra -o sumprimes sumprimes.c -lm

看看这产生的警告,它会提醒你一些问题,当然是相当小的问题。

我可以通过检查看到的主要直接问题是您的程序肯定会出现段错误,因为您使用 malloc() 分配的存储空间太小了 sizeof(int) 的一个因子,您已经忽略了。

splint 这样的静态错误检查器可以帮助您检测更多问题;但是,没有必要盲目地遵循它的所有建议:一旦您了解所有建议,您就可以决定遵循哪些建议。

其他几点说明:

  • “幻数”,例如代码中的 100,被认为是非常错误的形式。根据经验,代码中应该出现的唯一数字是 0(零),而且只是有时。您的 100 可以更好地表示为 named(如 const int 或更传统的 #define),以表明其含义。
  • 以代码中的方式“突出”变量声明是非常规的
  • 如果一个函数被宣传为返回一个值,您应该始终检查它是否有错误,例如确保malloc()的返回值不是NULL,检查scanf()的返回值(如果你使用的话)是期望值等
  • 作为一般的风格问题,在 C 中通常认为是一种良好的做法,即每行声明一个变量并带有简短的解释性注释。也有例外,但这是一个合理的经验法则。
  • 对于任何类型的输入,scanf() 都是一个糟糕的选择,因为它会以难以预测的方式改变 stdin 的状态,除非输入完全符合预期,您可以永远不要依赖。如果您想读取整数,最好将stdinfgets() 上可用的内容读入缓冲区,然后使用strtol(),因为这样您可以进行更有效的错误检查和报告.
  • 不建议再投malloc()的return。

希望这会有所帮助。

【讨论】:

  • 我为他修复了缩进的变量——悄悄地——同时修复了问题本身的一些其他问题。好答案。您可能会提到明确检查来自 scanf() 的返回 - 以及 malloc()
  • 谢谢。我修复了很多你建议的内容,重新更新了我的代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-08
  • 1970-01-01
  • 2013-01-22
相关资源
最近更新 更多