质数索引位置c程序

时间:2018-08-09 16:47:18

标签: c++ recursion

#include <stdio.h>
#include <bitset>

using namespace std;

short smallprimes[549]; // about 1100 bytes
char in[19531]; // almost 20k

int isprime(int j) {
    if (j < 3)
        return j == 2;
    for (int i = 0; i < 549; i++) {
        int p = smallprimes[i];
        if (p * p > j)
            break;
        if (!(j % p))
            return 0;
    }
    return 1;
}

void init() {
    bitset<4000> siv;
    for (int i = 2; i < 64; i++)
        if (!siv[i])
            for (int j = i + i; j < 4000; j += i)
                siv[j] = 1;
    int k = 0;
    for (int i = 3; i < 4000; i += 2)
        if (!siv[i]) {
            smallprimes[k++] = i;
        }

    for (int a0 = 0; a0 < 10000000; a0 += 512) {
        in[a0 / 512] = !a0;
        for (int j = a0 + 1; j < a0 + 512; j += 2)
            in[a0 / 512] += isprime(j);
    }
}

int whichprime(int k) {
    if (k == 2)
        return 1;
    int a = k / 512;
    int ans = 1 + !a;
    for (int i = 0; i < a; i++)
         ans += in[i];
    for (int i = a * 512 + 1; i < k; i += 2)
         ans += isprime(i);
    return ans;
}

int main() {
    int k;
    init();
    while (1 == scanf("%i", &k)) 
        printf("%i\n", whichprime(k));
}

这是我的代码。它显示数组中素数的索引值。 我想要小的代码可以获取存储在数组中的质数的索引值。或者我输入素数,然后程序计算该特定索引处的素数并显示其索引位置。

输入:2

输出:1(数组中的索引)

这很复杂。寻找替代解决方案。

1 个答案:

答案 0 :(得分:0)

这是我针对此问题的较不复杂(魔术数字更少)的通用C方法。像OP的原始代码一样,如果将非素数传递给索引,则会产生不良结果:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>

typedef unsigned long PRIME;

bool *primes;
size_t calloc_size = 3;

void sieve(PRIME end) {

    if (end >= calloc_size) {
        primes = realloc(primes, end + 1);
        memset(primes + calloc_size, true, end - calloc_size + 1);
        calloc_size = end + 1;
    }

    // This might be optimized to not resieve old territory ...
    for (size_t i = 0; i <= end; i++) {
        if (primes[i]) {
            for (size_t j = i * 2; j <= end; j += i) {
                primes[j] = false;
            }
        }
    }
}

// whichprime() returns 1-based index of target prime in primes array.
// Current and future results are indeterminate if argument isn't prime.

size_t whichprime(PRIME prime) {

    if (prime < calloc_size) {
        for (size_t i = 0, idx = 0; i < calloc_size; i++) {
            if (primes[i]) {
                idx++;

                if (i == prime) {
                    return idx; // Target prime already in primes array
                }
            }
        }
        assert(false); // should never be reached
    }

    sieve(prime);

    return whichprime(prime); // recurse as we now know it's in primes
}

int main() {

    PRIME k;

    // This could be optimized to not store even numbers ..
    primes = calloc(calloc_size, sizeof(bool));
    primes[calloc_size - 1] = true;

    while (1 == scanf("%lu", &k)) {
        printf("%lu\n", whichprime(k));
    }

    free(primes);

    return 0;
}

布尔primes数组是一个根据需要扩展的筛子。

用法

> ./a.out
2999
430
859433
68301
13
6
7919
1000
>
相关问题