for循环的值意外下降

时间:2019-03-27 01:17:18

标签: c for-loop primes

哥德巴赫猜想指出,每个4上的偶数都是两个素数的和,我正在用C编写一个程序来查找这些对。为此,它首先查找所有小于用户给定数字的质数。我有一个for循环,从4迭代到用户给定的数字,并在循环体内找到对。当该循环达到约40时,突然回跳约30,然后继续迭代(在用户输入50时,它从38跳到9,在输入60时,它从42跳到7)。我不知道为什么会这样。这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/types.h>
#include <unistd.h>

struct pair{
    int a;
    int b;
}pair_t;


int main(){
    int N;
    int numPrimes = 1;
    int *primes = malloc(100*sizeof(int));
    int isPrime = 1;
    primes[0] = 2;
    int timesRealloc = 0;
    int availableSlots = 100;

    printf("Please enter the largest even number you want to find the Goldbach pair for: \n");
    scanf("%d", &N);

    struct pair pairs[N/2 + 4];

    int j = 0;
    int i;
    for (i = 3; i <= N; i+=2){ 
        j = 0;
        isPrime = 1;
        while (primes[j] <= sqrt(i)) {
            if (i%primes[j] == 0) {
                isPrime = 0;
                break;
            }
            j++;
        }
        if (isPrime == 1){
            primes[numPrimes] = i;
            numPrimes++;
        }
        if (availableSlots == numPrimes){
            timesRealloc++;
            availableSlots += 100;
            primes = realloc(primes, availableSlots*sizeof(int));
        }
    }

    printf("The largest prime I found was %d\n", primes[(numPrimes-1)]);

    int k;
    for (i=4; i<=N; i+=2){
        printf("i is %d, N is %d\n", i, N);
        if (i > N){ break; }
        for (j=0; j<numPrimes; j++){
            for (k=0; k<numPrimes; k++){
                int sum = primes[j] + primes[k];
                if(sum == i){
                    pairs[i].a = primes[j];
                    pairs[i].b = primes[k];
                }
            }
        }
    }

    for (i=4; i<=N; i+=2){
        printf("%d is the sum of %d and %d\n", i, pairs[i].a, pairs[i].b);
    }

    return 0;
}

1 个答案:

答案 0 :(得分:0)

您尝试通过压缩pairs数组以使其仅容纳其他(偶数)个数字并从4而不是零开始,以节省空间。但是,您错误地计算了它的大小,然后在使用它时,将其视为未压缩,并且每个自然数都有一个插槽。

该代码在main()中与其他代码一起进行素数数组计算,因此最好将其分开。当寻找对时,它不会在找到对时退出,也不会在它开始获得大于目标的总和时退出。我在下面的工作中尝试解决所有这些问题:

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

#define INITIAL_SLOTS (100)

struct pair {
    int a;
    int b;
} pair_t;

int compute_primes(int limit, unsigned **primes, int size) {
    int numPrimes = 0;

    (*primes)[numPrimes++] = 2;

    for (int i = 3; i <= limit; i += 2) { 
        bool isPrime = true;

        for (int j = 0; (*primes)[j] <= i / (*primes)[j]; j++) {
            if (i % (*primes)[j] == 0) {
                isPrime = false;
                break;
            }
        }

        if (isPrime) {
            (*primes)[numPrimes++] = i;
        }

        if (numPrimes == size) {
            size *= 2;
            *primes = realloc(*primes, size * sizeof(unsigned));
        }
    }

    return numPrimes;
}

int main() {
    int N;
    printf("Please enter the largest even number you want to find the Goldbach pair for: \n");
    scanf("%d", &N);

    unsigned *primes = calloc(INITIAL_SLOTS, sizeof(unsigned));
    int numPrimes = compute_primes(N, &primes, INITIAL_SLOTS);

    printf("The largest prime I found was %d\n", primes[numPrimes - 1]);

    struct pair pairs[(N - 4) / 2 + 1]; // compressed data structure

    for (int i = 4; i <= N; i += 2) {

        int offset = (i - 4) / 2; // compressed index
        bool found = false;

        for (int j = 0; ! found && j < numPrimes; j++) {
            for (int k = 0; ! found && k < numPrimes; k++) {
                int sum = primes[j] + primes[k];

                if (sum == i) {
                    pairs[offset].a = primes[j];
                    pairs[offset].b = primes[k];
                    found = true;
                } else if (sum > i) {
                    break;
                }
            }
        }
    }

    for (int i = 4; i <= N; i += 2) {
        int offset = (i - 4) / 2; // compressed index
        printf("%d is the sum of %d and %d\n", i, pairs[offset].a, pairs[offset].b);
    }

    free(primes);

    return 0;
}

输出

> ./a.out
Please enter the largest even number you want to find the Goldbach pair for: 
10000
The largest prime I found was 9973
4 is the sum of 2 and 2
6 is the sum of 3 and 3
8 is the sum of 3 and 5
10 is the sum of 3 and 7
12 is the sum of 5 and 7
14 is the sum of 3 and 11
...
9990 is the sum of 17 and 9973
9992 is the sum of 19 and 9973
9994 is the sum of 53 and 9941
9996 is the sum of 23 and 9973
9998 is the sum of 31 and 9967
10000 is the sum of 59 and 9941
>