求0到n之间素数个数的序列
要求:
(1) 找出0-1000之间素数
(2) 设f(n)表示0-n之间的素数个数,计算出当n=0,1,2,3,.....,997时f(n)的值,并写入文件
分析:
首先找素数使用一个效率较高的方法——Eratosthenes筛法,只要把1和不超过1000的正合数都删去。其原理为:由于正合数必有不可约数是小于等于其平方根的,只要首先求出1-1000平方根之间的全部不可约数,依次把这些不可约数之外的倍数也全部删去,剩下的正好就是不可约数。(参考《初等数论》)
其程序如下:
/**
* @param sieveSize: int 素数表的长度
* @return 素数表
*/
public ArrayList<Integer> primeSieve(int sieveSize){
boolean[] sieve = new boolean[sieveSize];
// 初始化都是素数
for (int i = 2; i < sieve.length; i++) {
sieve[i] = true;
}
sieve[0] = false;
sieve[1] = false;
// 筛选
int pointer;
for (int i = 2; i < (int)Math.sqrt(sieveSize)+1; i++) {
pointer = i*2;
while (pointer < sieveSize) {
sieve[pointer] = false;
pointer+=i;
}
}
// 返回素数
ArrayList<Integer> primes = new ArrayList<Integer>();
for (int i = 0; i < sieveSize; i++) {
if(sieve[i]==true)
primes.add(i);
}
return primes;
}
有了素数表,求f(n)就容易多了,但是只要遍历0-997,每一轮循环判断一下循环变量是否等于素数表中的某个数,等于就把当前f(n)设为某个数,否则等于前一个数,然而这样效率太低了,事实上素数表是有序的,只要不断遍历素数表相邻两个数为区间的序列,就能实现一次遍历完不需要判断
代码如下:
传入的参数array是素数表,len是所求序列的长度
public int[] countPrime(int[] array, int len) {
int[] result = new int[len];
result[0] = 0; result[1] = 0;
int begin, end;
int i = 2;
for (int j = 0; j < array.length-1; j++) { begin = array[j];
end = array[j+1];
result[i] += result[i-1]+1; System.out.printf("=====result[%d] = %d \n", i, result[i]);
i++;
begin++;
while (begin < end) {
result[i] = result[i-1];
System.out.printf("result[%d] = %d \n", i, result[i]);
begin++;
i++;
}
}
result[i] += result[i-1]+1;
System.out.printf("=====result[%d] = %d \n", i, result[i]);
return result;
}
把所求结果写入文件:经典的File+FileWriter+BufferedWriter即可,写入主函数
public static void main(String[] args) {
// TODO Auto-generated method stub
CryptoTechnology ct = new CryptoTechnology();
int maxNum = 1000;
System.out.println(maxNum + "以内的素数有:");
ArrayList<Integer> tableList= ct.primeSieve(maxNum);
ct.printIntegerList(tableList);
int[] tablearray = new int[tableList.size()];
int index = 0;
Iterator<Integer>it = tableList.iterator();
while (it.hasNext()) {
Integer integer = (Integer) it.next();
tablearray[index++] = integer;
}
int[] counter = ct.countPrime(tablearray, maxNum);
String content = "";
for (int i = 0; i < counter.length; i++) {
content += counter[i]+",";
}
System.out.println(content); File file = new File("src/zhaoke/primes.txt");
FileWriter fw;
try {
fw = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.close();
fw.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
求出结果得到一个文件,也就是F(n)随n变化的序列。
求出结果可以试试给f(n)画个图,使用python就很容易了,代码如下:
import matplotlib.pyplot as plt # 读取文件,得到一个字符串
with open('primes.txt') as f:
line = f.readline()
f.close() primes = line.split(',') # 字符串分割
primes = list(map(int, primes)) # 字符串列表转换为int列表
x = range(len(primes))
plt.plot(x, primes) # 画图 # 解决中文显示问题
plt.rcParams['font.sans-serif'] = ['KaiTi'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # plt.title('f(n)随n变化的图像')
plt.xlabel('自然数序列1,2,...,n')
plt.ylabel('小于某自然数的素数个数f(n)') plt.show()
如图:
求0到n之间素数个数的序列的更多相关文章
- 求n到m之间素数的个数
Description 求n到m之间素数的个数 Input 多组测试数据,每组先输入一个整数t,表示组数,然后每组输入2个正整数n和m,(1 <= n <= m <= 10000) ...
- Help Hanzo lightof 1197 求一段区间内素数个数,[l,r] 在 [1,1e9] 范围内。r-l<=1e5; 采用和平常筛素数的方法。平移区间即可。
/** 题目:Help Hanzo lightof 1197 链接:https://vjudge.net/contest/154246#problem/M 题意:求一段区间内素数个数,[l,r] 在 ...
- loj #6235. 区间素数个数 min_12.5筛
\(\color{#0066ff}{ 题目描述 }\) 求 \(1\sim n\) 之间素数个数. \(\color{#0066ff}{输入格式}\) 一行一个数 n . \(\color{#0066 ...
- 求 1~n 之间素数的个数
求1到n之间素数的个数 1. 筛选法 筛选掉偶数,然后比如对于 3,而言,筛选掉其整数倍数:(也即合数一定是某数的整数倍,比如 27 = 3*9) int n = 100000000; bool fl ...
- loj #6235. 区间素数个数
#6235. 区间素数个数 题目描述 求 1∼n 1\sim n1∼n 之间素数个数. 输入格式 一行一个数 n nn . 输出格式 一行一个数,表示答案. 样例 样例输入 10 样例输出 4 样例解 ...
- python3 filter用法(举例求0~n之间的素数)
在用python3求0~n之间的素数时,关于filter用法的有点模糊,于是上网查了一下filter用法. 求0~n之间素数的脚本prime.py: def f(x): plist = [0,0] + ...
- 【视频+图文】Java基础经典练习题(一)输出2-100之间的素数,及素数个数
目录 第一题:判断2-100之间有多少个素数,并输出所有素数. 1.视频讲解: 2.思路分析: 代码讲解:以i=4为例 4.为大家准备了彩蛋: 能解决题目的代码并不是一次就可以写好的 我们需要根据我们 ...
- POJ 3978 Primes(求范围素数个数)
POJ 3978 Primes(求范围素数个数) id=3978">http://poj.org/problem? id=3978 题意: 给你一个区间范围A和B,要你求出[A,B]内 ...
- 求小于n的素数个数
本文是对 LeetCode Count Primes 解法的探讨. 题目: Count the number of prime numbers less than a non-negative num ...
随机推荐
- Ubuntu通过Apache安装WebDav
使用KeePass保存密码,在个人服务器上安装WebDav协议. # 安装Apache2服务器 sudo aptitude install -y apache2 # 开启Apache2中对WebDav ...
- RESTfull是什么
经常做接口测试,会看很多接口文档,那怎么识别研发的接口设计是否足够规范,是否符合一些行业标准或准则.那认识了解RESTfull,可以让我们更具有专业性.让我们对接口文档的阅.接口合理性设计识别,做到有 ...
- JavaCV FFmpeg H264编码
上次成功通过FFmpeg采集摄像头的YUV数据,这次针对上一次的程序进行了改造,使用H264编码采集后的数据. (传送门) JavaCV FFmpeg采集摄像头YUV数据 采集摄像头数据是一个解码过程 ...
- 连Python产生器(Generator)的原理都解释不了,还敢说Python用了5年?
最近有很多学Python同学问我,Python Generator到底是什么东西,如何理解和使用.Ok,现在就用这篇文章对Python Generator做一个敲骨沥髓的深入解析. 为了更好地 ...
- ConcurrentHashMap源码解析,多线程扩容
前面一篇已经介绍过了 HashMap 的源码: HashMap源码解析.jdk7和8之后的区别.相关问题分析 HashMap并不是线程安全的,他就一个普通的容器,没有做相关的同步处理,因此线程不安全主 ...
- LR之Oracle 2tier协议录制Oracle脚本
在一次测试中,需用到sql去查询Oracle数据,并去使用改数据时,查阅各种资料终于实现LoadRunner对Oracle数据库进行操作,分享给大家,也与大家共同进步~ 同时也可用Loadrunn ...
- 浅谈Samsung Exynos4412处理器
转载于:http://www.cnblogs.com/android210/archive/2013/01/16/2862349.html Topic:浅谈Samsung Exynos4412处理器( ...
- 3.Android网络编程-http介绍
1.HTTP请求方法 根据HTTP标准,HTTP请求可以使用多种请求方法. HTTP1.0定义了三种请求方法: GET(查), POST(改)和 HEAD(获取报头,一般用来测试链接是否正常)方法. ...
- 写给前端同学的C++入门教程(一):概述和环境搭建
说明:本人是前端er,因为最近对 UE4(一个游戏开发引擎)产生了兴趣,而这个引擎源开发游戏时需要用到 C++ ,所以就开始入坑 C++ 了.现将自己学习 C++ 的笔记整理并分享出来,以便一些想入门 ...
- HDU - 6736 F - Forest Program
题意 给你n个点m条边,并且保证整个图是仙人掌. 仙人掌:每条边仅属于1条或者0条回路 且无重边和自环 让你删掉一些边使其变成一棵树(拥有点数-1条边) 注意一个点也是森林 图可能是不联通的 思路 考 ...