曾经第一次面试题中的题目, 今天碰巧看到整理一下

当时用了最基本的算法写出来了, 两个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面试题的更多相关文章

  1. C语言复习---用筛选法求100之内的素数

    #include <stdio.h> #include <stdlib.h> #include <math.h> int main() { int i, j; ] ...

  2. Python练习题 026:求100以内的素数

    [Python练习题 026] 求100以内的素数. ------------------------------------------------- 奇怪,求解素数的题,之前不是做过了吗?难道是想 ...

  3. while做法1.兔子生兔子 2.求100以内质数的和3.洗发水15元 牙膏5元 香皂2元 150元的算法

    1.兔子生兔子 2.求100以内质数的和 3.150块钱花完问题

  4. while:1.兔子生兔子问题 2.打印菱形 3.求100以内质数的和4.洗发水15元一瓶,牙膏5元一支,香皂2元一块,150元刚好花完

    1.兔子生兔子问题: 2.打印菱形 3.求100以内质数的和 4.洗发水15元一瓶,牙膏5元一支,香皂2元一块,150元刚好花完有多少种情况?

  5. for嵌套:1.兔子生兔子问题 2.打印菱形 3.求100以内质数的和

    1.兔子生兔子问题 方法一: 方法二: 2.打印菱形 3.求100以内质数的和

  6. hdu 1856 求集合里元素的个数 输出最大的个数是多少

    求集合里元素的个数 输出最大的个数是多少 Sample Input41 23 45 61 641 23 45 67 8 Sample Output42 # include <iostream&g ...

  7. python求100以内素数

    python求100以内素数之和 from math import sqrt # 使用isPrime函数 def isPrime(n): if n <= 1: return False for ...

  8. 斐波那契数列(递归)&求100以内的素数

    Java 5 添加了 java.util.Scanner 类,这是一个用于扫描输入文本的新的实用程序.它是以 前的 StringTokenizer 和 Matcher 类之间的某种结合.由于任何数据都 ...

  9. 求100以内所有奇数的和,存于字变量X中。

    问题 求100以内所有奇数的和,存于字变量X中. 代码 data segment x dw ? data ends stack segment stack db 100 dup(?) stack en ...

随机推荐

  1. Java编程的逻辑 (51) - 剖析EnumSet

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

  2. 前端入门10-JavaScript语法之对象

    声明 本系列文章内容全部梳理自以下几个来源: <JavaScript权威指南> MDN web docs Github:smyhvae/web Github:goddyZhao/Trans ...

  3. linux学习笔记-linux主机上传下载文件至linux虚拟机的方法

    我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! 1.上传文件 scp -r file 用户名@ip地址:目标目录 2.下载文件 scp -r 用户名@ip地址:文件 目标目录

  4. SAP freelancer夫妻并不难!你也可以!

    SAP freelancer夫妻并不难!你也可以! 在笔者看来,如果能有每月超过10万的家庭收入,要是去上海滩购买单价在八万以上的房子,应该是可以轻松应对,想买就可以买,根本不用眨眼睛,不用一丁点儿的 ...

  5. 算法题丨Remove Duplicates from Sorted Array

    描述 Given a sorted array, remove the duplicates in-place such that each element appear only once and ...

  6. ORA-00471: DBWR process terminated with error案例

    每年年底,系统管理员都要组织一次容灾方案的测试.演练.会在一个与生产环境网络隔离的DR环境中,启动各个"生产环境服务器",然后让各路人员参与其中测试.演练容灾方案是否可靠.这次演练 ...

  7. sql server中嵌套事务*

    转自 https://www.cnblogs.com/guanjie20/archive/2013/02/17/2914488.html 我们在写事务时经常遇到的问题如下: 消息 266,级别 16, ...

  8. c/c++ linux 进程 fork wait函数

    linux 进程 fork wait函数 fork:创建子进程 wait:父进程等待子进程结束,并销毁子进程,如果父进程不调用wait函数,子进程就会一直留在linux内核中,变成了僵尸进程. for ...

  9. SQLServer查询计划

    参考:http://blog.csdn.net/luoyanqing119/article/details/17022649 1. 开启方式 菜单栏:query---Display Estimated ...

  10. 进程命令(tasklist)

    TaskList命令: // 描述: 显示本地或远程计算机上正在运行的进程列表信息. // 语法: tasklist [/s <computer> [ /u [<domain> ...