要求:

(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. javascript之判断数组的几种方法

    今天和小伙伴一起出去吃饭,有个小伙伴突然问我,你是前端是吧,问一下现在前端判断数组都有哪些方法,哈哈不知道是不是考我,当时没有说全,吃过饭后看了下自己以前的小笔记这里总结一下目前知道的所有对于数组的判 ...

  2. pycharm里面同级目录的py文件引用报错

    使用pycharm开发py遇到很烦的事儿,就是在同级目录引用另外一个py文件,pycharm里面总是会红杠,代码还是 照样可以跑,只是看着烦. 查询了一下,通过将当前目录设置为sources_root ...

  3. Windows 编程基础

    1 Windows应用程序的分类 1.1 控制台程序 DOS程序,本身没有窗口,通过WINDOWS下的DOS窗口执行. 1.2 窗口程序 拥有自己的窗口,通过窗口可以和用户进行交互.(比如:记事本,画 ...

  4. EntityFramwork基础用法

    一.EntityFramework(简称"EF")是什么? 在.NET3.5之前,我们经常编写ADO.NET代码或通过封装好的数据库访问层来与数据库进行交互,进行CRUD操作.这种 ...

  5. Signature Scanning(中文暂时译为"特征码扫描")是在C++(起码我是用C++^^)开发中很好的一种方式

    1.介绍 本文主要简单介绍在没有代码的情况下,如何从一个动态链接库中获取某个函数的址.主要实现方式为Signature Scanning(特征码扫描) 2.什么是Signature Scanning( ...

  6. day42 Pyhton 并发编程05

    一.内容回顾 # 线程 # 正常的编程界: # 进程 # 计算机中最小的资源分配单位 # 数据隔离 # 进程可以独立存在 # 创建与销毁 还有切换 都慢 给操作系统压力大 # 线程 # 计算机中能被C ...

  7. Kibana详细入门教程

    Kibana详细入门教程   目录 一.Kibana是什么 二.如何安装 三.如何加载自定义索引 四.如何搜索数据 五.如何切换中文 六.如何使用控制台 七.如何使用可视化 八.如何使用仪表盘 一.K ...

  8. tr命令-转换和删除字符

    tr 转换和删除字符 支持标准输入 格式 tr [OPTION]...SET1[SET2] Translate, squeeze, and/or delete characters from stan ...

  9. 普通人如何站在时代风口学好AI?这是我看过最好的答案

    摘要:当前,数据.算法.算力的发展突破正推动AI应用的逐步落地. AI是什么? 根据维基百科的定义,人工智能是一种新的通用目的技术(GPT, General Purpose Technology),它 ...

  10. eclipse 开发常见问题集锦

    问题1: eclipse导入外部项目,中文显示乱码(如下图) 方案:项目名-->右键属性-->如下图: 问题2: jsp/html页面eclipse双击打开,代码在工作区不显示(如下图:) ...