求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 ...
随机推荐
- LPCTSTR的含义
LPCTSTR: LP代表指针.C代表不可改变.T代表根据是否定义UNICODE宏而分别define为char或wchar_t.STR代表字符串. 例如: LPCTSTR lp="BMP F ...
- Lane-Detection 近期车道线检测论文阅读总结
近期阅读的几篇关于车道线检测的论文总结. 1. 车道线检测任务需求分析 1.1 问题分析 针对车道线检测任务,需要明确的问题包括: (1)如何对车道线建模,即用什么方式来表示车道线. 从应用的角度来说 ...
- vue : 无法加载文件 C:\Users\Lenovo\AppData\Roaming\npm\vue.ps1,因为在此系统上禁止运行脚本。
第一步:用管理员身份打开 第二步:执行:set-ExecutionPolicy RemoteSigned 选择Y或A,回车
- 跟着动画学习 TCP 三次握手和四次挥手
TCP三次握手和四次挥手的问题在面试中是最为常见的考点之一.很多读者都知道三次和四次,但是如果问深入一点,他们往往都无法作出准确回答. 本篇尝试使用动画来对这个知识点进行讲解,期望读者们可以更加简单地 ...
- devops构建IT服务供应链
1. devops构建IT服务供应链 1) 什么是devops devops是 "开发" 和"运维"的缩写 devops是一组最佳实践强调(IT研发.运维. ...
- vscode设置snippets
自动添加文件描述信息 "File Comments": { "prefix": "filecomments", "body&quo ...
- AT一万亿港元市值之差,腾讯和阿里到底“差”在哪里?
很少有人注意到,港股之王已经悄然易主. 2019年底,阿里巴巴赴港二次上市,中国两大互联网巨头终于有了统一的比较口径,同台竞技之下,我们发现一个惊人事实--截止9月5日,港股阿里巴巴市值5.9万亿港元 ...
- CSP-S2020AFO记
2020-10.11 考初赛辣. 选择题考了一堆时间复杂度,一个不会(卒) 我寻思这01背包哪里能用贪心? 啊,这,这,这手写快排竟如此简单,手写取Max,手写队列,两个字符串颠来倒去,竟活到爆! 震 ...
- Linux关联文件扩展名和打开程序
手动为Linux关联文件扩展名与打开程序. 当Linux不认识某种扩展名的时候,需要为此扩展名创建一个MIME类型.Linux是依据MIME类型而不是扩展名来决定打开程序的. 再将此种MIME类型与某 ...
- idea创建servlet工程初体验
servlet工程创建 前提:创建项目之前需要配置java环境变量 和tomcat配置,配置完成后进入如下操作. tomcat 安装和配置参考 https://www.cnblogs.com/xush ...