- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章C++ 实现求小于n的最大素数的实例由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
C++ 实现求小于n的最大素数的实例 。
枚举就是基于已有知识镜像答案猜测的一种问题求解策略 。
问题:求小于n的最大素数 。
分析:
找不到一个数学公式,使得根据N就可以计算出这个素数 。
我们思考:
N-1是素数么?N-2是素数吗?... 所以我们就是判断N-K是否为素数: N-K是素数的充分必要条件:N-K不能被[2,n-k)中任何一个整除 判断N-K是否为素数的问题可以转化为: 求小于N-K的全部素数(求“小于N的最大素数”中的条件是“n不能被[2,n)中任意一个素数整除”,而不是整数) 不能被[2,n)中任意一个素数整除的数一定是素数,因为那些整数都是以素数为因子的, 所以没必要检测所有整数,检测所有素数就ok了 。
解决方法:
2是素数,记为PRIM 0 。
根据PRIM 0,PRIM 1,...PRIM K,寻找比PRIM K大的最小素数PRIM K+1(这里是根据素数找素数) 。
如果PRIM K+1大于N,则PRIM K是我们需要找的素数,否则继续寻找 。
枚举:
从可能的集合中一一列举各元素 根据所知道的知识,给一个猜测的答案 比如:2是素数,那2是本问题的解么 。
枚举算法:
对问题可能解集合的每一项: 根据问题给定的检验条件判断哪些是成立的 使条件成立的即为问题的解 。
枚举过程:
判断猜测答案是否正确 2是小于N的最大素数么? 进行新的猜测:
有两个关键因素要注意:
1. 猜测的结果必须是前面的猜测中没有出现过的。每次猜测的素数一定要比已经找到的素数大 2. 猜测的过程中要及早排除错误的答案。比如:除2之外,只有奇数才可能是素数 。
枚举过程中需要考虑的问题:
1. 给出解空间,建立简介的数学模型 可能的情况是什么? 模型中变量数尽可能的少(使规模尽量小),他们之间相互独立 求“小于N的最大素数”中的条件是“n不能被[2,n)中任意一个素数整除” 而不是“n不能被[2,n)中任意一个整数整除” 。
2. 减少搜索的空间 。
利用知识缩小模型中各变量的取值范围,避免不必要的计算 比如:较少代码中循环体执行的次数 除2之外,只有奇数才可能是素数,{2,2*i+1|1<=i,2*i+1<n} 。
3. 采用合适的搜索顺序 。
搜索空间的遍历顺序要与模型中条件表达式一致 例如:对{2,2*i+1|1<=i,2*i+1<n},按照从小到大的顺序 。
枚举关键字(枚举核心):
减少规模 。
实例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
#include <iostream>
using
namespace
std;
int
prim[50000];
//用来存所有素数
int
primNum=0;
//用来记录 prim数组中已经存入的素数的数量
int
times=0;
//用于记录求解问题的总共判断次数
int
primLessN(
int
n);
int
primLessN_2(
int
n);
bool
isPrimMothed(
int
n);
//判断一个数是否为素数
/*
方法一:由前往后用素数判断的枚举法:
求“小于N的最大素数”中的条件是“n不能被[2,n)中任意一个素数整除”,而不是整数
当n=10 0000时,
ans=99991
times=4626 4478次
primNum=9592
我每一个素数被判断出来,都要遍历一下之前的素数表
而判断10 0000的时候,外层循环走了50000,里层每一个素数就是一次之前素数表的遍历
50000*(1+2+3+...+9592)=50000* 4600 8082
前面那个数没有50000,还要减去那些非素数
从 50000* 4600 8082可以看出,主要是之前那些素数花的时间,非素数几乎没花时间
非素数= 4626 4478-4600 8082= 25 6450
只有25万,虽然还是要比下面多很多,因为是从前往后比较的
*/
int
primLessN(
int
n)
{
prim[0]=2;
//2是最小的素数
primNum++;
for
(
int
i=3;i<n;i+=2){
bool
isPrim=1;
//isPrim用来判断一个数是否为素数
for
(
int
j=0;j<primNum;j++){
times++;
if
(i%prim[j]==0){
isPrim=0;
break
;
//没加break之前, 当n=10 0000时,times=2 5239 6936次 (2.5亿) ,加了之后times=4626 4478次 (4.5千万次)
}
}
if
(isPrim) prim[primNum++]=i;
//如果是素数,则存入prim素数数组
}
return
prim[primNum-1];
}
/*
方法二: 由后往前的整数枚举法
而且方法二的空间消耗也少
当n=10 0000时,
ans=99991
times=346次
当n=100 0000时,用方法一的话,根本算不出来
ans=99 9983
times=1811次
当n=1 0000 0000(一亿)时,
ans=9999 9989
times=11314次
当n=10 0000 0000(十亿)时,
ans=9 9999 9937
times=52537次
*/
bool
isPrimMothed(
int
n){
bool
isPrim=1;
//isPrim用来判断一个数是否为素数
if
(n==2||n==3)
return
1;
for
(
int
i=2;i*i<=n;i++){
times++;
if
(n%i==0)
return
0;
}
return
1;
}
int
primLessN_2(
int
n){
for
(
int
i=n;i>=2;i--){
if
(isPrimMothed(i))
return
i;
}
}
int
main(){
int
n;
scanf
(
"%d"
,&n);
//int ans=primLessN(n);
int
ans=primLessN_2(n);
cout<<ans<<endl;
printf
(
"总判断次数times:%d\n"
,times);
printf
(
"总素数数primNum:%d\n"
,primNum);
return
0;
}
|
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持! 。
原文链接:http://www.cnblogs.com/Renyi-Fan/p/6922940.html 。
最后此篇关于C++ 实现求小于n的最大素数的实例的文章就讲到这里了,如果你想了解更多关于C++ 实现求小于n的最大素数的实例的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我看到以下宏 here . static const char LogTable256[256] = { #define LT(n) n, n, n, n, n, n, n, n, n, n, n,
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
所以我得到了这个算法我需要计算它的时间复杂度 这样的 for i=1 to n do k=i while (k<=n) do FLIP(A[k]) k
n 的 n 次方(即 n^n)是多项式吗? T(n) = 2T(n/2) + n^n 可以用master方法求解吗? 最佳答案 它不仅不是多项式,而且比阶乘还差。 O(n^n) 支配 O(n!)。同样
我正在研究一种算法,它可以在带有变音符号的字符(tilde、circumflex、caret、umlaut、caron)及其“简单”字符之间进行映射。 例如: ń ǹ ň ñ ṅ ņ ṇ
嗯..我从昨天开始学习APL。我正在观看 YouTube 视频,从基础开始学习各种符号,我正在使用 NARS2000。 我想要的是打印斐波那契数列。我知道有好几种代码,但是因为我没有研究过高深的东西,
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭12 年前。 Improve th
谁能帮我从 N * N * N → N 中找到一个双射数学函数,它接受三个参数 x、y 和 z 并返回数字 n? 我想知道函数 f 及其反函数 f',如果我有 n,我将能够通过应用 f'(n) 来
场景: 用户可以在字符串格式的方程式中输入任意数量的括号对。但是,我需要检查以确保所有括号 ( 或 ) 都有一个相邻的乘数符号 *。因此 3( 应该是 3*( 和 )3 应该是 )*3。 我需要将所有
在 Java 中,表达式: n+++n 似乎评估为等同于: n++ + n 尽管 +n 是一个有效的一元运算符,其优先级高于 n + n 中的算术 + 运算符。因此编译器似乎假设运算符不能是一元运算符
当我阅读 this 问题我记得有人曾经告诉我(很多年前),从汇编程序的角度来看,这两个操作非常不同: n = 0; n = n - n; 这是真的吗?如果是,为什么会这样? 编辑: 正如一些回复所指出
我正在尝试在reveal.js 中加载外部markdown 文件,该文件已编写为遵守数据分隔符语法: You can write your content as a separate file and
我试图弄清楚如何使用 Javascript 生成一个随机 11 个字符串,该字符串需要特定的字母/数字序列,以及位置。 ----------------------------------------
我最近偶然发现了一个资源,其中 2T(n/2) + n/log n 类型 的递归被 MM 宣布为无法解决。 直到今天,当另一种资源被证明是矛盾的(在某种意义上)时,我才接受它作为引理。 根据资源(下面
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 8 年前。 Improve th
我完成的一个代码遵循这个模式: for (i = 0; i < N; i++){ // O(N) //do some processing... } sort(array, array + N
有没有办法证明 f(n) + g(n) = theta(n^2) 还是不可能?假设 f(n) = theta(n^2) & g(n) = O(n^2) 我尝试了以下方法:f(n) = O(n^2) &
所以我目前正在尝试计算我拥有的一些数据的 Pearson R 和 p 值。这是通过以下代码完成的: import numpy as np from scipy.stats import pearson
ltree 列的默认排序为文本。示例:我的表 id、parentid 和 wbs 中有 3 列。 ltree 列 - wbs 将 1.1.12, 1.1.1, 1.1.2 存储在不同的行中。按 wbs
我的目标是编写一个程序来计算在 python 中表示数字所需的位数,如果我选择 number = -1 或任何负数,程序不会终止,这是我的代码: number = -1 cnt = 0 while(n
我是一名优秀的程序员,十分优秀!