要求:

(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之间素数个数的序列的更多相关文章

  1. 求n到m之间素数的个数

    Description 求n到m之间素数的个数 Input 多组测试数据,每组先输入一个整数t,表示组数,然后每组输入2个正整数n和m,(1 <= n <= m <= 10000) ...

  2. Help Hanzo lightof 1197 求一段区间内素数个数,[l,r] 在 [1,1e9] 范围内。r-l<=1e5; 采用和平常筛素数的方法。平移区间即可。

    /** 题目:Help Hanzo lightof 1197 链接:https://vjudge.net/contest/154246#problem/M 题意:求一段区间内素数个数,[l,r] 在 ...

  3. loj #6235. 区间素数个数 min_12.5筛

    \(\color{#0066ff}{ 题目描述 }\) 求 \(1\sim n\) 之间素数个数. \(\color{#0066ff}{输入格式}\) 一行一个数 n . \(\color{#0066 ...

  4. 求 1~n 之间素数的个数

    求1到n之间素数的个数 1. 筛选法 筛选掉偶数,然后比如对于 3,而言,筛选掉其整数倍数:(也即合数一定是某数的整数倍,比如 27 = 3*9) int n = 100000000; bool fl ...

  5. loj #6235. 区间素数个数

    #6235. 区间素数个数 题目描述 求 1∼n 1\sim n1∼n 之间素数个数. 输入格式 一行一个数 n nn . 输出格式 一行一个数,表示答案. 样例 样例输入 10 样例输出 4 样例解 ...

  6. python3 filter用法(举例求0~n之间的素数)

    在用python3求0~n之间的素数时,关于filter用法的有点模糊,于是上网查了一下filter用法. 求0~n之间素数的脚本prime.py: def f(x): plist = [0,0] + ...

  7. 【视频+图文】Java基础经典练习题(一)输出2-100之间的素数,及素数个数

    目录 第一题:判断2-100之间有多少个素数,并输出所有素数. 1.视频讲解: 2.思路分析: 代码讲解:以i=4为例 4.为大家准备了彩蛋: 能解决题目的代码并不是一次就可以写好的 我们需要根据我们 ...

  8. POJ 3978 Primes(求范围素数个数)

    POJ 3978 Primes(求范围素数个数) id=3978">http://poj.org/problem? id=3978 题意: 给你一个区间范围A和B,要你求出[A,B]内 ...

  9. 求小于n的素数个数

    本文是对 LeetCode Count Primes 解法的探讨. 题目: Count the number of prime numbers less than a non-negative num ...

随机推荐

  1. LPCTSTR的含义

    LPCTSTR: LP代表指针.C代表不可改变.T代表根据是否定义UNICODE宏而分别define为char或wchar_t.STR代表字符串. 例如: LPCTSTR lp="BMP F ...

  2. Lane-Detection 近期车道线检测论文阅读总结

    近期阅读的几篇关于车道线检测的论文总结. 1. 车道线检测任务需求分析 1.1 问题分析 针对车道线检测任务,需要明确的问题包括: (1)如何对车道线建模,即用什么方式来表示车道线. 从应用的角度来说 ...

  3. vue : 无法加载文件 C:\Users\Lenovo\AppData\Roaming\npm\vue.ps1,因为在此系统上禁止运行脚本。

    第一步:用管理员身份打开 第二步:执行:set-ExecutionPolicy RemoteSigned 选择Y或A,回车

  4. 跟着动画学习 TCP 三次握手和四次挥手

    TCP三次握手和四次挥手的问题在面试中是最为常见的考点之一.很多读者都知道三次和四次,但是如果问深入一点,他们往往都无法作出准确回答. 本篇尝试使用动画来对这个知识点进行讲解,期望读者们可以更加简单地 ...

  5. devops构建IT服务供应链

    1. devops构建IT服务供应链   1) 什么是devops devops是 "开发" 和"运维"的缩写 devops是一组最佳实践强调(IT研发.运维. ...

  6. vscode设置snippets

    自动添加文件描述信息 "File Comments": { "prefix": "filecomments", "body&quo ...

  7. AT一万亿港元市值之差,腾讯和阿里到底“差”在哪里?

    很少有人注意到,港股之王已经悄然易主. 2019年底,阿里巴巴赴港二次上市,中国两大互联网巨头终于有了统一的比较口径,同台竞技之下,我们发现一个惊人事实--截止9月5日,港股阿里巴巴市值5.9万亿港元 ...

  8. CSP-S2020AFO记

    2020-10.11 考初赛辣. 选择题考了一堆时间复杂度,一个不会(卒) 我寻思这01背包哪里能用贪心? 啊,这,这,这手写快排竟如此简单,手写取Max,手写队列,两个字符串颠来倒去,竟活到爆! 震 ...

  9. Linux关联文件扩展名和打开程序

    手动为Linux关联文件扩展名与打开程序. 当Linux不认识某种扩展名的时候,需要为此扩展名创建一个MIME类型.Linux是依据MIME类型而不是扩展名来决定打开程序的. 再将此种MIME类型与某 ...

  10. idea创建servlet工程初体验

    servlet工程创建 前提:创建项目之前需要配置java环境变量 和tomcat配置,配置完成后进入如下操作. tomcat 安装和配置参考 https://www.cnblogs.com/xush ...