求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 ...
随机推荐
- BootStrap之 提示工具(Tooltip)插件
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- tomcat 大并发报错 Maximum number of threads (200) created for connector with address null and port 80
1.INFO: Maximum number of threads (200) created for connector with address null and port 80 说明:最大线程数 ...
- [MySQL] timestamp和datetime的区别和大坑
1.timestamp占用4个字节;datetime占用8个字节2.timestamp范围1970-01-01 00:00:01.000000 到 2038-01-19 03:14:07.999999 ...
- C# 合并Excel工作表
文档合并.拆分是实现文档管理的一种有效方式.在工作中,我们可能会遇到需要将多个文档合并的情况,那如何来实现呢,本文将进一步介绍.关于拆分Excel工作表,可参见这篇文章——C#如何拆分EXCEL工作表 ...
- Java开发笔记(十六)非此即彼的条件分支
前面花了大量篇幅介绍布尔类型及相应的关系运算和逻辑运算,那可不仅仅是为了求真值或假值,更是为了通过布尔值控制流程的走向.在现实生活中,常常需要在岔路口抉择走去何方,往南还是往北,向东还是向西?在Jav ...
- Spring Boot 整合 docker
一.什么是docker ? 简介 Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs ...
- 常用的String原型
对于常用的字符串原型的举例 在字符串末尾追加字符串 String.prototype.append = function (str) { return this.concat(str);} 删除指定索 ...
- eclipse配置freemarker,*.ftl文件
亲测,提供2种方式,效果都不错: ----------------------------------------- 1.直接下载相应的插件.只需要下载FreeMarker的识别Jar包就可以:888 ...
- 浅谈TCP IP协议栈(二)IP地址
上一节大致了解TCP/IP协议栈是个啥东西,依旧是雾里看花的状态,有很多时候学一门新知识时,开头总是很急躁,无从下手,刚学会一点儿,却发现连点皮毛都不算,成就感太低,所以任何时候学习最重要的是要在合适 ...
- python--继承--方法的重写---和父类的扩展
1.方法的重写 父类的方法不能满足子类的需要,可以对方法重写 具体的实现方式,就相当于在子类中定义了一个和父类同名的方法并实现 重写之后只会对子类的方法调用,而不会调用父类封装的方法 2.对父类方法进 ...