面试时的一道题

fmonkey 2004-08-07 01:24:20
编程求前1000个质数 注意时空效率

...全文
787 37 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
wodeyouxian 2004-08-10
  • 打赏
  • 举报
回复
紧急补充:

1、强烈建议用筛法,这样对效率有很大的提高。
2、请不要用函数调用,这不利于效率
3、在循环中有判断时,请把判断写在外面(程序要做少量的改动),因为每一次判断都可能打断cpu的流水线作业,这在很大程度上违背了局部性原则,(计算机基础中有讲过的,不知道的应该补补了),对于这种大量循环应该写在外面,程序虽然不简捷,但是对效率有很大的提升。
4、书写程序的时候最好用规范点的方法,你是去求职的,写得规范一定有好处的。
freshairfly 2004-08-09
  • 打赏
  • 举报
回复
楼上的算法好,可是这需要对质数有研究吧
楼上说的规律偶就不知道
fmonkey 2004-08-09
  • 打赏
  • 举报
回复
既然大家如此的热情那我不如把我这次面试的另外两道题写出来
重开一贴,欢迎各位参与

hardeggwang 2004-08-09
  • 打赏
  • 举报
回复
不做成函数,如下:效率还可以
#include <iostream.h>
main()
{
cout<<"1:\t2"<<endl;
cout<<"2:\t5"<<endl;
int num = 2;
int j;
for(int i = 7; num < 1000; i += 2)
{
for (j = 3; j <= i / 2; j += 2)
{ if( i % j == 0 )
break;
}
if( j >= i / 2 )
{ num += 1;
cout<<num<<":\t"<<i<<endl;
}

}
}
LLnju 2004-08-09
  • 打赏
  • 举报
回复
楼上的有病啊,别人用伪码写程序不行啊,知道意思就行了.

求前1000个素数(甚至前1M个)用的时间应该是以毫秒计

贴个运行很慢的来,求3-1M的素数,咔咔

const size_t MaxPrePrime = 0X100000;

unsigned* preprimetab = NULL;
size_t szpreprimetablen = 0;

struct __genpreprimetab {
enum { sztmpbuf = MaxPrePrime / 2 };
__genpreprimetab()
{
assert( !preprimetab && !szpreprimetablen );
int i , cur = 0;
unsigned* tmp = new unsigned[ sztmpbuf ];
for( i = 3; i < MaxPrePrime; i += 2 ) tmp[ ( i - 3 ) / 2 ] = i;
for( i = 0; i < sztmpbuf; ++i )
if( tmp[i] ) filteronce( tmp , tmp[i] );
for( i = 0; i < sztmpbuf; ++i )
if( tmp[i] ) ++szpreprimetablen;
preprimetab = new unsigned[szpreprimetablen];
for( i = 0; i < sztmpbuf; ++i )
if( tmp[i] ) preprimetab[cur++] = tmp[i];
delete[]tmp;

}
~__genpreprimetab()
{
delete[]preprimetab;
szpreprimetablen = 0;
}
private:
void filteronce( unsigned* ptr , unsigned prime )
{
assert( ptr && ( prime & 1 ) );
unsigned ntime = MaxPrePrime / prime;
for( unsigned n = 3; n <= ntime; n += 2 )
ptr[ ( n * prime - 3 ) >> 1 ] = 0;
}
} __preinit;
贵阳的乡巴佬 2004-08-09
  • 打赏
  • 举报
回复
楼上,

说一下,

你用哪个编译器编译过了,

我也试一下.

应该是一个不错的编译器
贵阳的乡巴佬 2004-08-09
  • 打赏
  • 举报
回复
哪个弱智,
这一程序能编译得过吗?
有点怪了,
哪有这种定义数组的,
不出错真的就怪了.
C有这种定义数组的语法吗?
int m, y;
printf("Please input a number:");
scanf("%d", &m);
int p[m];
庄鱼 2004-08-09
  • 打赏
  • 举报
回复
给出一个精简的算法,看看哪位有更好的。本方法内存占用也不是很高,对1,000,000而言运行开销也就9M多点
/----------------------------------
// 素数序列快速生成算法 作者:FreeFice / Ziyun
// 适用于32位/64位系统。 本代码释放到公用域,任何人均可复制传播与引用,但
// 必须保证算法的完整性,不得全部或部分的声明为私有,否则即构成侵权行为。
//---------------------------------

#define MaxNum 1000 //1000000生成时间约1分钟

//-------公开的素数序列算法部分-------------
// 原理:依据足够大的素数其个位数是 1 3 7 9 的原则,构筑奇数筛子
// 运用累加步进的方法,避免使用大量的除法及开方操作,通过检测自身
// 已生成序列的界值,达到推定当前奇数运算范围。生成序列最少四个,
// 最多2147483647个
void InitPrime(int Max,__int64 *Prime)
{
Prime[0] = 2; Prime[1]=3; Prime[2]=5;
int m = 3,t=1;
for (__int64 n=7; m<Max;n+=2){
if (n%5==0)continue;
__int64 s = Prime[t]*Prime[t];
if (n>=s)t++;
if (n==s)continue;
for (int i=1;i<t;i++)
if(n % Prime[i]==0)goto NEXT;
Prime[m++]=n;
NEXT:
}
}
//--------------------------------------

int main()
{
__int64 *Primes = new __int64[MaxNum];
InitPrime(MaxNum,Primes);
//----------省略输出语句
delete[]Primes;
return 0;
}
沧海桑人 2004-08-09
  • 打赏
  • 举报
回复
#include <iostream.h>
#include <conio.h>
#include <alloc.h>

int isPrime(int n, int *p);

main()
{
int m, y;
printf("Please input a number:");
scanf("%d", &m);
int p[m];
//*p = (int*)malloc(sizeof(int)*m);
int count = isPrime(m, p);
for(y = 0; y < count; y++)
{
printf("%d\n", p[y]);
}
getch();
}

int isPrime(int n, int *p)
{
int x, j, con;
int *tmp;
tmp = p;
con = 0;
for(j = 3; j < n; j++)
{
for (x = 2; x < j; x++)
{
if ((j % x) != 0)
{
p[con] = j;
continue;
}
else
{
con--;
break;

}
con++;
}
return con;
}
LLnju 2004-08-09
  • 打赏
  • 举报
回复
搜了一下还搜到啦,咔咔

http://search.csdn.net/search.asp?key=10G+%CB%D8%CA%FD&class=&size=10&option=advance&x=31&y=8
LLnju 2004-08-09
  • 打赏
  • 举报
回复
求一个范围内的素数用筛法还是比较好的,像这样的筛法效率还是比较高的,咔咔
取 N = 前几个素数的乘积 如 2 * 3 * 5 * 7 * 11 * 13 , 对于大于 3 * N 的数可以写成 X = a * N + b 的形式, 显然的要 g c d( b , N ) = 1 才是素数,这样可以预先过滤掉大部分的非素数。
然后就可以像常规的筛法筛选素数啦,段的大小要选择适当,不要超过高速缓存的大小

至于求素数个数的程序我就看不懂了郁闷啊

郁闷,我怎么写g c d( b , N ) 也不行啊
LLnju 2004-08-09
  • 打赏
  • 举报
回复
这个问题讨论过N百次了,很早以前有较好的算法,求 10G 类的素数只要 50秒( C2 450上 ),求10G内素数个数只要10秒以下,咔咔,你在CSDN上搜以下就可以了
ntxs 2004-08-08
  • 打赏
  • 举报
回复
mark
iwdc 2004-08-08
  • 打赏
  • 举报
回复
mark
begar 2004-08-08
  • 打赏
  • 举报
回复
上次去华为面试就有这个题
leiyry18 2004-08-08
  • 打赏
  • 举报
回复
只在奇数中判断
庄鱼 2004-08-08
  • 打赏
  • 举报
回复
有更好的筛子。
一个足够大的素数的个位只能是:1、3、7、9,这样可以用累加法来过滤奇数里可能的合数。速度比上述的任何一种方法都要快几个数量级。通常1,000,000个也就分吧分钟的事
antijpn 2004-08-08
  • 打赏
  • 举报
回复
到底是要时间还是要空间啊?两个都要显然是不切实际的
wodeyouxian 2004-08-08
  • 打赏
  • 举报
回复
#include<iostream>
using namespace std;


void main()
{
int i,n,co=0,flag=1;
for(n=2;n<10000&&co<1000;n++)
{
for(i=2;i<=n/2;i++)
if(n%i==0)
{flag=0;
break ;} //判断是不是素数,不是的话就将标志flag设为0;

if(flag==0) //标志为0就跳到下一个数去
{
flag=1;
continue;
}

cout<<n<<" ";
co++;

}


cin.get();
}
//这是我写的一个小程序,可以实现1000个素数的求解,因为对效率有要求,所以建议不要写成函数调用,因为每次的调用和返回值都有较多的开销。当然,我用的是一种很笨的算法,楼主可以采用筛选法,那么在循环的次数上要少很多的,不过这又有另一个问题,就是要将以前的素数全部有备份,那就要使用数组,最有效的当然是动态的数组。很明显,这要加大空间的开销,而且写起来要麻烦一点
如果楼主特别的强调效率的话,可以将n和i设为register变量,这也有一点效
这个程序可以运行,最后一个数为7917
楼主也可以将其中的一些值改一下,比方说求前十个,前五个,

楼主面试过了不妨告诉一下我们楼主的经验啊。^_^
liubinbill 2004-08-08
  • 打赏
  • 举报
回复
#include <iostream>
#include <math.h>
using namespace std;

bool Isprime(int num)
{
if(num<2)
return false;
if(num==2)
return true;
if(num%2==0)
return false;
for(int i=3;i<sqrt(num);i+=2)
{
if(num%i==0)
return false;
}
return true;
}

int FindNext(int cur)
{
int i=cur+1;
while(!Isprime(i))
{
i++;
}
return i;
}

void main()
{
int count=0;
int cur=1;
while(count<1000)
{
cur=FindNext(cur);
cout<<cur<<ends;
count++;
}
}
加载更多回复(17)

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧