求100之内的素质并输出(最优算法)-PHP面试题
曾经第一次面试题中的题目, 今天碰巧看到整理一下
当时用了最基本的算法写出来了, 两个for循环, 一个一个取余, 是质数就放进结果数组中
代码如下, 检查代码运行时间的代码是来对比三种不同算法的优劣性
算法一: 每个数都从2开始除, 除遍所有比自己小的整数, 如果有能整除的, 说明不是质数, 退出本次循环, 进行下一次循环
function test()
{
$start = microtime(true); //程序开始时间
// 一定要加true !!!
// 一定要加true !!!
// 一定要加true !!!
$array = array(); //存放质数
for ($i=2; $i < 40001; $i++) {
$mark = 0; //是否质数的标记 0质数, 1非质数
for ($j=2; $j < $i; $j++) {
if(($i % $j) === 0)
{
$mark = 1; //有能整除的就说明不是质数, 退出本次循环
break;
}
} if($mark != 1)
{
$array[] = $i; //存放质数
} } echo "<pre>";
print_r($array);
echo "<br>";
echo microtime(true)-$start;
}
面试官看了后让我优化一下算法, 当时我的代码连break好像都没有, 然后我就加了句break, 然后信心满满的看着他,
哈哈, 然后你可以想象下他的表情了~
不过, 他人还挺好, 告诉我并不需要每次都除到比自己小1的那个数, 我第一反应是除到一般就够了,
然后他说, 除到这个数的平方根就可以了, 比如17除到4就行了, 因为当除数超过平方根后, 再除只是把商和除数的位置颠倒了而已, 是一种重复
算法二: 除了把第二个for循环中的$i 换成 sqrt($i) 之外基本没什么变化
function test1()
{
$start = microtime(true);
$array = array();
for ($i=2; $i < 40001; $i++) {
$mark = 0;
for ($j=2; $j <= sqrt($i); $j++) {
if(($i % $j) === 0)
{
$mark = 1;
break;
}
} if($mark != 1)
{
$array[] = $i;
} } // echo "<pre>";
// print_r($array);
echo "<br>";
echo microtime(true)-$start;
}
当然还有一种算法, 质数是什么? 非质数是什么?
质数就是除了自己和1 之外不能被任何数整除, 非质数就是合数, 而合数则肯定可以由质数相乘得到.
通过这个规则, 我们就可以只检查$i 是否可以整除比自己小的质数了, 非质数可以丢掉不管了.(此时的效率还不如算法二高)
还可以再结合算法二, 只检查比$i平方根小的质数, (这时的效率就比算法二高了)
算法三: 这种算法效率最高
function test2()
{
$start = microtime(true);
$queue = array(); //用一个数组来模拟队列, 发现质数就放到队列尾部,
$queue[] = 2;
for ($i=2; $i < 40001; $i++) {
$mark = 0;
foreach ($queue as $key => $value) { //只检查比$i平方根小的质数
if($value >= sqrt($i))
{
break;
} //foreach循环队列, 如果能整除队列中的质数, 则说明$i不是质数, 应该立刻跳出循环
if(($i % $value) === 0)
{
$mark = 1;
break;
}
} if($mark != 1)
{
$queue[] = $i; //如果$i是质数, 追加到队列尾部, 方便下次循环使用
} } // echo "<pre>";
// print_r($queue);
echo "<br>";
echo microtime(true)-$start;
}
你可以依次运行
test();
test1();
test2();
来检查结果和代码运行时间, 运行前请根据需要打开或者关闭注释
求100之内的素质并输出(最优算法)-PHP面试题的更多相关文章
- C语言复习---用筛选法求100之内的素数
#include <stdio.h> #include <stdlib.h> #include <math.h> int main() { int i, j; ] ...
- Python练习题 026:求100以内的素数
[Python练习题 026] 求100以内的素数. ------------------------------------------------- 奇怪,求解素数的题,之前不是做过了吗?难道是想 ...
- while做法1.兔子生兔子 2.求100以内质数的和3.洗发水15元 牙膏5元 香皂2元 150元的算法
1.兔子生兔子 2.求100以内质数的和 3.150块钱花完问题
- while:1.兔子生兔子问题 2.打印菱形 3.求100以内质数的和4.洗发水15元一瓶,牙膏5元一支,香皂2元一块,150元刚好花完
1.兔子生兔子问题: 2.打印菱形 3.求100以内质数的和 4.洗发水15元一瓶,牙膏5元一支,香皂2元一块,150元刚好花完有多少种情况?
- for嵌套:1.兔子生兔子问题 2.打印菱形 3.求100以内质数的和
1.兔子生兔子问题 方法一: 方法二: 2.打印菱形 3.求100以内质数的和
- hdu 1856 求集合里元素的个数 输出最大的个数是多少
求集合里元素的个数 输出最大的个数是多少 Sample Input41 23 45 61 641 23 45 67 8 Sample Output42 # include <iostream&g ...
- python求100以内素数
python求100以内素数之和 from math import sqrt # 使用isPrime函数 def isPrime(n): if n <= 1: return False for ...
- 斐波那契数列(递归)&求100以内的素数
Java 5 添加了 java.util.Scanner 类,这是一个用于扫描输入文本的新的实用程序.它是以 前的 StringTokenizer 和 Matcher 类之间的某种结合.由于任何数据都 ...
- 求100以内所有奇数的和,存于字变量X中。
问题 求100以内所有奇数的和,存于字变量X中. 代码 data segment x dw ? data ends stack segment stack db 100 dup(?) stack en ...
随机推荐
- 轻松搞定RocketMQ入门
RocketMQ是一款分布式.队列模型的消息中间件,具有以下特点: 能够保证严格的消息顺序 提供丰富的消息拉取模式 高效的订阅者水平扩展能力 实时的消息订阅机制 亿级消息堆积能力 RocketMQ网络 ...
- springmvc 文件上传(粘贴即用)
这里记录下,方便以后复制粘贴. maven配置 <dependency> <groupId>commons-fileupload</groupId> <art ...
- 教你快速撸一个免费HTTPS证书
摘要: 免费 HTTPS 证书,了解一下? HTTPS 已成为业界标准,这篇博客将教你申请Let's Encrypt的免费 HTTPS 证书. 本文的操作是在 Ubuntu 16.04 下进行,使用 ...
- 安装PackageControl
安装PackageControl 1,到PackageControl官网,查找到相应sublime text的版本安装信息, sublime text 3: import urllib.request ...
- Canvas:时钟
这个时钟是将钟盘的圆心点移到了 canvas 画布中心点.以方便后面的方位计算 ctx.translate(width/2,height/2); 现定义一个圆盘来显出这个时钟的基本位置 ctx.sav ...
- 在ubuntu16.04中再次体验.net core 2.0
在上一篇文章中在ubuntu16.04中初次体验.net core 2.0 简单介绍了一下ubuntu中运行.net core 2.0.配置nginx反向代理以及安装supervisor守护进程……本 ...
- SuperMap iClient 如何使用 WMTS 地图服务(转载)
原文链接: WMTS服务初步理解与读取 https://blog.csdn.net/supermapsupport/article/details/76806670 SuperMap iClient ...
- Apex 中的自定义迭代器
迭代器 迭代器(iterator)可以遍历一个集合变量中的每个元素.Apex提供了Iterator接口来让开发者实现自定义的迭代器. Iterator接口 Iterator接口定义了两个函数: has ...
- 自定义一个全屏的AlertDialog。
........... final MyDialog dialog = new MyDialog(this); LayoutInflater inflater = getLayoutInflater( ...
- Android为TV端助力context转换类型