- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试使用带位数组的埃拉托色尼筛法查找素数,但我使用的是无符号整数数组。我需要能够生成多达 2,147,483,647 个素数。我的代码有效并且可以生成大约 10,000,000,但是当我增加数组的大小时以容纳更大的数字时它失败了。有人可以指导我如何将位 vector 与 c(不是 c++)一起使用。谢谢
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#define MAXBYTES 2000000
#define MAX 50000000
#define BITSIZE 32
void ClearBit(unsigned int [], unsigned int);
void SetBit(unsigned int [], unsigned int);
int BitVal(unsigned int [], unsigned int);
void PrintBitStream(unsigned int [], unsigned long);
void PrintBitStreamData(unsigned int[], unsigned long);
int Sieve(unsigned int[], unsigned int, unsigned int);
int main(int argc, char ** argv) {
unsigned int maxsize = MAX;
unsigned int i;
//Set Bit Array
unsigned int BitArray[MAXBYTES] = {0};
SetBit(BitArray, 0);
SetBit(BitArray, 1);
i = 2;
for (;i < maxsize;i++){
if(Sieve(BitArray, i, maxsize)==0)
break;
}
PrintBitStreamData(BitArray, maxsize-1);
return EXIT_SUCCESS;
}
void PrintBitStreamData(unsigned int BitArray[], unsigned long maxsize) {
unsigned int i;
for (i = 0; i < maxsize; i++)
if (!BitVal(BitArray, i))
printf("%ld ", i);
printf("\n");
}
void PrintBitStream(unsigned int BitArray[], unsigned long maxsize) {
unsigned int i;
for (i = 2; i < maxsize; i+=2)
printf("%d", BitVal(BitArray, i));
printf("\n");
}
void SetBit(unsigned int BitArray[], unsigned int pos) {
BitArray[pos / BITSIZE] |= 1 << (pos % BITSIZE);
}
void ClearBit(unsigned int BitArray[], unsigned int pos) {
BitArray[pos / BITSIZE] &= ~(1 << (pos % BITSIZE));
}
int BitVal(unsigned int BitArray[], unsigned int pos) {
return ((BitArray[pos / BITSIZE] & (1 << (pos % BITSIZE))) != 0);
}
int Sieve(unsigned int BitArray[], unsigned int p, unsigned int maxsize) {
unsigned int i;
unsigned int j;
j = 0;
for (i = 2 * p; i < maxsize; i += p) {
SetBit(BitArray, i);
j++;
}
return j;
}
最佳答案
我绝对不会使用位数组,而是使用原生 int 数组(64 位或 32 位取决于体系结构)并环绕一个函数以将普通数字重新映射到正确的位置并使用位 |
和 &
。
还要考虑去掉偶数,几乎没有一个是素数。因此,您可以将前 128 个数字存储在第一个 64 位数字中,接下来的 128 个数字存储在第二个数字中,依此类推。
听起来有点复杂,但实际操作起来很有趣!
欧拉计划似乎产生了一些非常好的解决方案。
好处是:筛选时不需要重新计算偶数-奇数转换,但是您可以取消设置每三位用于筛选 3,每五位取消设置用于筛选 5 等。
如果您需要快速的 Java 解决方案作为详细引用,请加入聊天。
EDIT4:更正了工作代码,但仍然很慢。备注:记得使用 calloc!
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <limits.h>
#include <time.h>
typedef unsigned long long number;
number lookFor = 2147483648ULL;
number max = 2147483648ULL*10ULL; // hopefully more then every 10th uneven number is prime
unsigned long * isComposite;
number bitslong = CHAR_BIT*sizeof(long);
time_t rawtime;
struct tm * timeinfo;
char buffer[80];
// is not called during sieve, only once per sieving prime
// and needed for reading if a number is prime
inline long getParts(number pos, number *slot, unsigned int *bit){
*slot = pos / bitslong;
*bit = (unsigned int)(pos % bitslong);
}
int isPrime(number n){
if(n == 1){
return 0;
}
if(n < 4){
return 1;
}
if((n%2) == 0){
return 0;
}
number slot=0;
unsigned int bit=0;
number pos = (number)(n-3)/2;
getParts(pos, &slot, &bit);
// printf("? n=%lld pos = %lld slot = %lld bit = %lu ret %d \n", n, pos, slot, bit, !(isComposite[slot] & (1<<bit)));
return !(isComposite[slot] & (1UL<<bit));
}
// start sieving at offset (internal position) offset with width step
int doSieve(number offset, number step){
rawtime = time(0);
time (&rawtime);
timeinfo = localtime (&rawtime);
strftime(buffer, 80, "%Y-%m-%d %H:%I:%S", timeinfo);
unsigned int bit=0;
number slot=0;
getParts(offset, &slot, &bit);
printf("doSieve %s %lld %lld %lu \n", buffer, offset, step, isComposite[slot]);
while(slot < max/bitslong){
slot += (step + bit)/bitslong;
bit = (step + bit) % bitslong;
isComposite[slot] |= (1UL << bit);
}
return 1;
}
int sieve(){
number spot;
spot=1;
number pos;
pos = 0;
while(spot < 1 + sqrt((float)max)){
spot+=2;
if(! isPrime(spot)){
pos++;
continue;
}
doSieve(pos, spot);
pos++;
}
}
void main(int argc, char *argv[]){
if(argc > 1){
char *tp = malloc(sizeof(char*));
max = strtol(argv[1], &tp, 10);
}
printf("max %lld , sq %ld, malloc: %lld\n", max, (long)(1 + sqrt((float)max)), 1+max/bitslong);
isComposite = calloc((2+max/bitslong), sizeof(unsigned long)) ;
if(! isComposite){
printf("no mem\n");
exit(5);
}
sieve();
number i;
number found = 0;
for(i = 1; i<max && found < lookFor; i++){
if(isPrime(i)){
found++;
// printf(" %30lld %30lld \n", found, i);
if(found % 10000 == 0 ){
printf("%30lld %30lld \n", found, i);
}
}
/*
if(i % 1000 == 17){
printf("%5lld %5lld \n", i, found);
}
*/
}
}
关于c - Eratosthenes 位数组筛法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16885615/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 6年前关闭。 Improve this qu
我有实体: @Entity @Table(name = "CARDS") public class Card { @ManyToOne @JoinColumn(name = "PERSON_I
我正在尝试计算二维多边形的表面法线。我正在使用 OpenGL wiki 中的 Newell 方法来计算表面法线。 https://www.opengl.org/wiki/Calculating_a_S
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 7 年前。 Improve
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 9 年前。 Improve this
我这里有以下 XML: Visa, Mastercard, , , , 0, Discover, American Express siteonly, Buyer Pay
即将发生的 Google 政策变更迫使我们实现一个对话框,以通知欧盟用户有关 Cookie/设备标识符用于广告和分析的情况。我只想向欧盟用户显示此对话框。我不想使用额外的权限(例如 android.p
本文分享自华为云社区《华为大咖说 | 企业应用AI大模型的“道、法、术” ——道:认知篇》,作者:华为云PaaS服务小智。 本期核心观点 上车:AGI是未来5~10年内,每个人都无法回避的技
我有一个与酒精相关的网站,需要先验证年龄,然后才能让他们进入该网站。我使用 HttpModule 来执行此操作,该模块检查 cookie,如果未设置,我会将它们重定向到验证页面。我验证他们的年龄并存储
在欧盟,我们有一项法律,要求网页请求存储 cookie 的许可。我们大多数人都了解 cookie 并同意它们,但仍然被迫在任何地方明确接受它们。所以我计划编写这个附加组件(ff & chrome),它
以下在 C 和/或 C++ 中是否合法? void fn(); inline void fn() { /*Do something here*/ } 让我担心的是,第一个声明看起来暗示函数将被定义
我是一名优秀的程序员,十分优秀!