#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
(数组中的索引)
这很复杂。寻找替代解决方案。
答案 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
>