Java:2-200内的质数
关注:118 答案:3 mip版
解决时间 2021-01-30 01:33
提问者巴黎左岸
2021-01-29 22:27
输出2-200内的质数。这道题怎么做呢?各位大虾帮忙!
最佳答案
二级知识专家可爱暴击
2021-01-29 22:50
楼上是最佳解,说得不清楚,我补充一下,已知2为质数,输出它,则划去其后能被2整除的数,然后看3,因为3不能被2整除,则3未被划去,我们认为它是质数,输出它,然后划去3的倍数,如此继续,遇到被划去的数就越过,遇到未被划去的数就输出,并划去其倍数,批量输出质数这种方法效率是我见过最高的,被称为埃色特尼筛法,你可以通过一个boolean数组和2个嵌套循环简单实现。
对于单个数,则检查其是否能被2到其平方根的数整除即可
全部回答
1楼笑尽沧桑
2021-01-30 00:00
质数筛选法:
筛法原理,一个素数不能被它平方根以内的所有素数的倍数筛掉,它就是素数。此法用于大数(如一百万、一千万)这种很管用。
对这个,200以内的就必须知道sqrt(200)内的质数,也就是14以内的质数,然后开一个201的boolean数组,把14以内下标为质数的项的值值为true,其余大于14的项都置为true,然后,把14以内的质数扫描一遍,对每个质数,它的k倍肯定不是质数,数组的这一项置为false;扫描完14内的所有质数后,开始时那个数组的所有为true的项的下标就是质数了…………
附上我们浙大的论坛内部流传过的一个算法:
筛选一万亿内任意一个区段的素数
函数参数:as_1 decimal value 筛选范围区段起点
as_2 decimal value 筛选范围区段终点
as_return[] decimal reference 存放种子素数
as_return_value[] decimal reference 存放筛选结果
调用详解:1.必须定义的变量 dec as_return[],as_return_value[]
2.as_return,as_return_value切勿赋值。
3.筛选区段一般不大于100万为佳,即as_2-as_1<=1000000,
函数允许区段超过100万。
4.调用本函数f_prime_number(as_1,as_2,as_return,as_return_value)
5.as_return_value[]就是生成的某区段内的素数
函数返回:>=0 所找到素数的个数
<0 error
实际调用:求一万亿最后一个一万区段的素数
f_prime_number(999999990001.0,1000000000000.0,as_return,as_return_value)
要点及原理:
一.筛100万内素数:
1.筛法原理,一个素数不能被它平方根以内的所有素数的倍数筛掉,它就是素数。
2.100万的平方根是1000,所有只用1000以内的素数就可以筛出100万内所有素数
3.根据上面所说,程序分两步,第一步1000以内进行筛选,第二部把1000以上的筛选
剩下的素数挑选出来
4.第一步的具体思路:
a.定义数组:p[1000001],数组下标表示数本身,初值为0,筛选时把素数的整数倍置为-1,
剩下为0的元素即为素数
b.2是素数,其倍数是偶数,由程序滤掉,不再筛
c.筛选从种子的平方开始,因为其平方以内的的数以被前面的素数筛过了
d.筛选的步长用种子的2倍,因为用种子作步长有一半是偶数,筛过了
二.筛一万亿内的素数
1.一万亿的内的素数不宜一下子全筛出来,可以一次以100万为单位,一个区段一个区段筛。
2.算法要点如下:
a.一万亿的平方根为100万,用100万以内的素数可以筛出一万亿内的所有素数,所以函数
首先自行计算一次100万以内的素数存入数组as_return。
b.定义数组p[1000001],其下标与区段内的自然序号相对应,元素值0为素数,1不是
c.根据as_return内的素数筛选至种子的平方大于筛选区间的上限
d.计算出每个种子在指定区间内筛掉的第一个数,然后按种子长度筛下去。
程序中语句为“j=as_return -mod(k1,as_return)”,如i=12,as_return=37
则j=21,所以令p[21]=1,即将k1+21筛掉(k1为区间起始值)再按步长37筛下去
e.偶数仍由程序筛掉,所以素数2不用
f.数组p元素加上区间起始值k1就是实际要求的素数
三.求更大的素数,如求1000万平方(100万亿)内的素数
方法一,把本函数涉及到100万的地方扩大10倍,即ls_rang=10000000,p[10000001],这样
就可以求出1000万平方内的所有素数,但会有一定的时间和资源开销,具体要看
实际硬件配置。
方法二,使用本函数计算出1000万内的素数作为种子存放在数组或文件中,再使用
本函数的后半部分(内部函数2)筛选1万亿以上部分的素数。
方法二的实际调用示例:
//求1万亿后第一个一万区段的素数
dec as_return[],as_return_value[],temp[],k
f_prime_number(1,10000000,as_return,as_return_value)
as_return=as_return_value
as_return_value=temp
k=f_prime_number(1000000000001.0,1000000010000.0,as_return,as_return_value)
四,函数的特殊调用:
为了提高效率(实际测试效果不明显),可以直接传入种子素数求大素数,如求1亿内最后一个
一百万的素数,实际用1万以内的素数作为种子就可以求出,而不用函数自行求出100万内的素数
作为种子,以提高效率和节省资源。调用示例如下:
dec as_return[],as_return_value[],temp[],k
f_prime_number(1,10000,as_return,as_return_value)
as_return=as_return_value
as_return_value=temp
k=f_prime_number(109000001.0,100000000.0,as_return,as_return_value)
五.注 意,修改或移植本函数是请务必考察目标系统规定的数据类型的精度,防治数据溢出。
六.函数代码特点:
函数通过标志变量,把原本需三个函数完成的功能捆绑在了一个函数中,并通过变量的指示
来完成递归。
2楼你的偏见
2021-01-29 23:24
提示:只能被1和自己整除的数! 我要你追加分数哦!不给追加分以后就不帮你了,嘿嘿
NND 墨迹 我直接来代码!!
2种方法供选折!
public class ZhiShu {
public static void main(String[] args)
{
int sum1=1;
for(int i=2;i<500000;i++)
{
if(i%2==1)
{
int j;
for(j=2;j<=Math.sqrt(i);j++)
{
if(i%j==0)
{
break;
}
}
if(j>Math.sqrt(i))
{
sum1++;//System.out.println(i);
}
}
}
System.out.println("共有"+sum1+"个质数");
//第二个方法!自己都测试一下,看看哪个快!呵呵,这个涉及到优化算法的问题,200以内看不出来,往大了写,就知道哪个好了!别以为死机啊,真的很慢的!
int sum=0;
for(int i=2;i<500000;i++)
{
int j;
for(j=2;j
{
if(i%j==0)
{
break;
}
}
if(j==i)
{
sum++;
//System.out.println(i);
}
}
System.out.println("共有"+sum+"个质数");
//System.out.println("2不是");
}
}
我要举报
如以上问答内容为低俗/色情/暴力/不良/侵权的信息,可以点下面链接进行举报,我们会做出相应处理,感谢你的支持!
→点此我要举报以上信息!←
推荐资讯