1、一群猴子围成一圈,按照1、2、……、n编号。 然后从第一个开始数,数到第m个,把它踢出圈外,再从前面开始数,数到第m个,把它踢出去……,以此类推,直到直到只剩下一只猴子,那只猴子就被称为国王。 需要编程模拟这个过程,输入m、n,输出最后一个国王的编号。
function king($n, $m){ $monkeys = range(1, $n); //创建1到n数组 $i=0; while (count($monkeys)>1) { //循环条件为猴子数量大于1 if(($i+1)%$m==0) { //$i为数组下标;$i+1为猴子标号 unset($monkeys[$i]); //余数等于0表示正好第m个,删除,用unset删除保持下标关系 } else { array_push($monkeys,$monkeys[$i]); //如果余数不等于0,则把数组下标为$i的放最后,形成一个圆形结构 unset($monkeys[$i]); } $i++;//$i 循环+1,不断把猴子删除,或 push到数组 } return current($monkeys); //猴子数量等于1时输出猴子标号,得出猴王}echo king(6,3);
2、有一头肉牛,到4岁就可以受孕,每年产一头牛。 同一头母猪将会出生。 15岁时就会绝育,无法再生育。 20岁就会死。问n年后会有多少头牛。
function niu($y){ static $num= 1; //定义静态变量;初始化牛的数量为1 for ($i=1; $i =4 && $i<15){ //每年递增来算,4岁开始+1,15岁不能生育 $num++; niu($y-$i); //递归方法计算小牛$num,小牛生长年数为$y-$i }else if($i==20){ $num--; //20岁死亡减一 } return $num;}
3、阳惠三角
<?php /* 默认输出十行,用T(值)的形式可改变输出行数 */class T{ private $num; public function __construct($var=10) { if ($varnum=$var; } public function display(){ $n=$this->num; $arr=array(); //$arr=array_fill(0,$n+1,array_fill(0,$n+1,0)); $arr[1]=array_fill(0,3,0); $arr[1][1]=1; echo str_pad(" ",$n*12," "); printf("%3d",$arr[1][1]); echo "
"; for($i=2;$i<=$n;$i++){ $arr[$i]=array_fill(0,($i+2),0); for($j=1;$j<=$i;$j++){ if($j==1) echo str_pad(" ",($n+1-$i)*12," "); printf("%3d",$arr[$i][$j]=$arr[$i-1][$j-1]+$arr[$i-1][$j]); echo " "; } echo"
"; } }}$yh=new T('3'); //$yh=new T(数量);$yh->display();?>
4.冒泡排序
function maopao($arr){ $len = count($arr); for($k=0;$k$k;$j--){ if($arr[$j]
5. 快速排序
function quickSort($arr) { //先判断是否需要继续进行 $length = count($arr); if($length <= 1) { return $arr; } //选择第一个元素作为基准 $base_num = $arr[0]; //遍历除了标尺外的所有元素,按照大小关系放入两个数组内 //初始化两个数组 $left_array = array(); //小于基准的 $right_array = array(); //大于基准的 for($i=1; $i $arr[$i]) { //放入左边数组 $left_array[] = $arr[$i]; } else { //放入右边 $right_array[] = $arr[$i]; } } //再分别对左边和右边的数组进行相同的排序处理方式递归调用这个函数 $left_array = quickSort($left_array); $right_array = quickSort($right_array); //合并 return array_merge($left_array, array($base_num), $right_array);}
6. 二分查找算法(Binary search Algorithm)
function binsearch($x,$a){ $c=count($a); $lower=0; $high=$c-1; while($lower$x){ $high=$middle-1; } elseif($a[$middle]
7.PHP特有的算法
<?phpfunction test(){ $a=1; $b=&$a; echo (++$a)+(++$a);}test();
PHP7以下的版本返回6,PHP7以下的版本返回5,这确实很奇怪。 个人认为底层算法较差,所以我认为是PHP7以下版本的BUG。
8.字符集:输入一个字符串,找到该字符串包含的字符集,并按顺序排序(英文)
function set($str){ //转化为数组 $arr = str_split($str); //去除重复 $arr = array_flip(array_flip($arr)); //排序 sort($arr); //返回字符串 return implode('', $arr);}
9、遍历一个文件下的所有文件以及子文件夹下的文件
function AllFile($dir){ if($dh = opendir($dir)){ while (($file = readdir($dh)) !== false){ if($file !='..' && $file !='.'){ if(is_dir($dir.'/'.$file)){ AllFile($dir.'/'.$file); //如果判断还是文件,则递归 }else{ echo $file; //输出文件名 } } } }}
10. 从标准 URL 中提取文件扩展名
function getExt($url) { $arr = parse_url($url); $file = basename($arr['path']);// basename函数返回路径中的文件名部分 $ext = explode('.', $file); return $ext[count($ext)-1]; }
11. 一个人想爬n级台阶。 他一次只能迈出1步或2步。 问题:这个人可以通过多少种方式完成该步骤?例如:总共有 3 个步骤。 您可以先进行步骤 1,然后进行步骤 2,也可以先进行步骤 2,然后进行步骤 1,也可以进行步骤 1 的步骤 3 次,总共 3 种不同的形式。
function jieti($num){ //实际上是斐波那契数列 return $num<2?1:jieti($num-1)+jieti($num-2);}
12.请写一段PHP代码,保证多个进程可以同时成功写入同一个文件。
13.无限分类
function tree($arr,$pid=0,$level=0){ static $list = array(); foreach ($arr as $v) { //如果是顶级分类,则将其存到$list中,并以此节点为根节点,遍历其子节点 if ($v['pid'] == $pid) { $v['level'] = $level; $list[] = $v; tree($arr,$v['id'],$level+1); } } return $list;}
14.获取上个月的第三天和最后三天
//获取上个月第一天 date('Y-m-01',strtotime('-1 month')); //获取上个月最后一天 date('Y-m-t',strtotime('-1 month'));
15.输入随机数可以查询对应的数据区间
//把区间换成数组写法,用二分法查找区间function binsearch($x,$a){ $c=count($a); $lower=0; $high=$c-1; while($lower=$x){ $high=$middle-1; }elseif($a[$middle]<=$x ){ $lower=$middle+1; } } return '在区间'.$a[$high].'到'.$a[$lower]; }$array = ['1','50','100','150','200','250','300'];$a = '120';echo binsearch($a,$array);
16、现在有一个字符串,需要对这个字符串进行n次运算,每次运算给出两个数字:(p,l)表示当前字符串中从下标p开始的字符宽度是la的子串。 你需要将子串左右翻转,直接插入到子串原来位置的后面,看看最终的字符串是什么。 字符串下标从0开始,您可以从示例中获取更多信息。
每组测试用例仅包含一组数据。 每组数据的第一行是原始字符串,宽度不超过10,仅包含大小写字符和数字。 会有一个数字n表示有n次操作,然后就有n行。 每行有两个整数,表示每个操作的(p,l)。
确保输入操作合法,且结果字符串宽度不超过1000。
str = $str; } public function run($orders) { foreach($orders as $item) { $this->execute($item[0],$item[1]); } return $this->str; } private function execute($pos,$length) { $len = strlen($this->str); if(($length-$pos) > $len) exit(1); else $tmp_str = substr($this->str,$pos,$length); $s1 = substr($this->str,0,$pos+$length); $s2 = substr($this->str,$pos+$length); $dest_str = $this->str_reverse($tmp_str); $this->str = $s1.$dest_str.$s2; } private function str_reverse($str) { $len = strlen($str); if($len%2 == 0) $times = $len/2; else $times = ($len-1)/2; for($i=0;$irun([[0,2],[1,3]]);echo $re;
17. 作为一名出道歌手,你终于要发行你的第一张专辑了。 您计划包含 n 首歌曲,每首歌曲的宽度为 s 秒。 每首歌曲必须完整包含在 CD 中。 每张CD的容量宽度为L秒,但至少要保证同一张CD上相邻两首歌曲之间至少有1秒的间隔。 为了辟邪,你决定任何CD上的歌曲数量都不能被数字13整除。那么制作这张专辑需要多少张CD呢?
每组测试用例只包含一组数据,每组数据第一行为三个正整数n、s、L。保证n≤100,s≤L≤10000
100 || $s>$l) exit('input error!'); $this->song_num = $n; $this->song_size = $s; $this->cd_size = $l; } public function run() { $cd_container = $this->calculate_single_cd(); return ceil($this->song_num/$cd_container); } private function calculate_single_cd() { //假设一张cd可以放n个 song_length+1 $n = floor($this->cd_size / ($this->song_size + 1)); //对剩余空间做判断 $gap = $this->cd_size - $n * ($this->song_size + 1); if($gap == $this->song_size)//剩余空间是否刚好可以放一首歌 if($n!=12)//已经放了12首歌,不要这最后的一首 $n += 1; else if($n == 13) //如果之前就已经可以放13首,放弃一首 $n = 12; return $n; }}$a = new TestKeenSting(7,2,6);$re = $a->run();echo $re;
18 用PHP实现单向队列
queue,$item); } public function addLast($item){ return array_push($this->queue,$item); } public function removeFirst(){ return array_shift($this->queue); } public function removeLast(){ return array_pop($this->queue); }}?>
19 请使用冒泡排序法对下面这组数据1023614102523859945进行排序。
<?php // 冒泡排序 function bubble_sort(&$arr){ for ($i=0,$len=count($arr); $i < $len; $i++) { for ($j=1; $j $arr[$j]) { $temp = $arr[$j-1]; $arr[$j-1] = $arr[$j]; $arr[$j] = $temp; } } } } // 测试 $arr = array(10,2,36,14,10,25,23,85,99,45); bubble_sort($arr); print_r($arr);?>
20 写一个排序算法(写代码),并说一下如何优化它。
<?php //快速排序 function partition(&$arr,$low,$high){ $pivotkey = $arr[$low]; while($low<$high){ while($low = $pivotkey){ $high--; } $temp = $arr[$low]; $arr[$low] = $arr[$high]; $arr[$high] = $temp; while($low
21 洗牌算法
<?php $card_num = 54;//牌数 function wash_card($card_num){ $cards = $tmp = array(); for($i = 0;$i < $card_num;$i++){ $tmp[$i] = $i; } for($i = 0;$i
【程序一】题目:经典问题:有一对狐狸,从出生后第三个月起每个月都会生一对狐狸,猴子长大后每个月都会生一对狐狸。第四个月,如果所有狐狸都没有死,每月总共生出多少只小狗?
1、程序分析:狐狸法则是数列1,1,2,3,5,8,13,21....
2表示第三个数字是前两个数字之和,这就是经典的斐波那契数列
function actionFblist($n) { // 1,1,2,3,5,8,13 // $n 为第n个月 $arr = [1,1]; if($n
【程序2】标题:判断101-200之间有多少个素数,并输出所有素数。
1、程序分析:判断素数的方法:用一个数除2去sqrt(这个数),如果能整除,
说明这个数不是素数,否则就是素数。
public function actionIsPrimeNumber(){ $arr = []; for ($i=101;$i<=200;$i++) { $flag = true; for ($j = 2;$j<=sqrt($i);$j++) { if($i % $j == 0) { $flag = false; } } if($flag == true) $arr[] = $i; } var_dump($arr);}
【程序3】标题:复制所有“蝴蝶兰编号”。 所谓“蝴蝶兰数”是指一个三位数,各数字的立方之和等于该数本身。 例如:153是一个“蝴蝶兰数”,因为153=1立方+5立方+3立方。
1、程序分析:使用for循环控制100-999个数字,将每个数字分解为个位、十位、百位。
public function actionWaterFlower(){ $re = []; for($i = 100;$i<= 999;$i++) { $hundred = floor($i / 100 ); // 获取百位数字 $ten = floor(($i 0 ) / 10 ); // 获取十位数字 $one = floor($i % 100 % 10); // 获取各位数字 if((pow($hundred,3) + pow($ten,3) + pow($one,3) ) == $i ) { $re[] = $i; } } var_dump($re);}
【程序4】题:利用条件运算符的嵌套完成这道题:成绩>=90分的朋友用A代表,分数在60-89之间的用B代表,分数低于60分的朋友代表由 C.
1. 程序分析: (a>b)?a:b 这是条件运算符的基本反例。
public function actionGetScore(){ $score = 90; if($score 100) return false; $re = $score >= 90 ? 'A' : ($score >= 60 ? 'B' :'C'); var_dump($re);}
【程序5】标题:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。 比如2+22+222+2222+22222(此时有5个数字相乘),几个数字的相乘是通过按钮控制的。
1、程序分析:关键是在循环中得到每一项的估计值。
2.可以使用php的str_repeat函数
public function actionRepeatN() { $a = 8; $n = 8; $sum = 0; for ($i = 0;$i
【程序6】标题:一个整数php 字符串排序,加100后是一个完全平方数,加168后又是一个完全平方数,这个数是多少?
1、程序分析:确定10万以内,先在开药前的数字上加100,然后在开药前的数字上加268,然后开药。 如果处方后的结果满足以下条件,即为结果。 请看详细分析:
一开始不知道如何判断一个数是否是完全平方数,可以根据php的基本函数sqrt和pow来间接判断
如果平方根四舍五入后平方等于原数,则这个数是完全平方数,按此方法判断
public function actionWhitchNum(){ for ($i=1;$i<=100000;$i++) { if(pow((int)sqrt($i+100),2) == ($i+100) &&pow((int)sqrt($i+168),2) == ($i+168) ) { echo $i; } } echo 'ok';}
【程序7】标题:输入某年某月某日,判断这三天是否是一年中的第几天?
1、程序分析:以3月5日为例,先加上前两个月,再加上5天,也就是一年中的第几天。 特殊情况,闰月和输入月份小于3需要考虑。 加一天。刚开始看这个问题,以为有一些简单的办法,没想到,没办法,只能用这些技巧
public function actionToday(){ $today = '2018-03-05'; // 格式固定 $days = explode('-',$today); $year = $days[0]; $month = (int)$days[1]; $day = (int)$days[2]; // 判断是否为闰年 $flag = false; if($year%400==0||($year%4==0&&$year0!=0)) { $flag = true; } // 对月份进行判断 1,3,5,7,8,10,12 为31天 // 4,6,9,11 为30天 // 2月份闰年为29天,否则为28天 switch ($month) { case 1: $sum = 0;break; case 2: $sum = 31;break; case 3: $sum = 59;break; case 4: $sum=90;break; case 5: $sum=120;break; case 6: $sum=151;break; case 7: $sum=181;break; case 8: $sum=212;break; case 9: $sum=243;break; case 10: $sum=273;break; case 11: $sum=304;break; case 12: $sum=334;break; default: break; } $sum = $sum + $day; if($flag && $month>2) $sum = $sum + 1; var_dump($sum);}
【程序8】 标题:输入三个整数x、y、zphp 字符串排序,请从小到大输出这三个数。
1.程序分析:我们想办法把最小的数放在x上,先比较x和y,如果x>y那么交换x和y的值,然后比较x和z,如果如果x >z,交换x和z的值,使得x可以最小化。
这里不将排序视为检查点。 对于排序,可以使用冒泡、快速、插入等排序算法。 这里使用了三种交换变量的方法。 我认为这很重要。
public function actionSortX(){ $x = 6; $y = 53; $z = 6; if($x>$y) // $y$z) { $tmp = $x; $x = $z; $z = $tmp; } if($y>$z) { $tmp = $y . '-' .$z; $tmp = explode('-',$tmp); $y = $tmp[1]; $z = $tmp[0]; } echo $x,',',$y,',',$z;}
【程序9】问题:输出9*9的公式。
1、程序分析:考虑分支和列,总共9行9列,i控制行,j控制列。
public function actionMultiplicationTable(){ for ($i=1;$i<=9;$i++) { for ($j=1;$j<=$i;$j++) { echo $j . '*' .$i .'=' . $i*$j; echo ' '; } echo "
"; }}
【程序10】问题:有一个分数序列:2/1、3/2、5/3、8/5、13/8、21/13...求该序列前20项的和。
1、程序分析:请把握分子和分母的变化。
public function actionAddFraction(){ $sum = 0; $numerator = [2,3]; $denominator = [1,2]; // 根据规律获得所有的分子和分母 for ($i=2;$i<20;$i++) { $numerator[$i] = $numerator[$i-2] + $numerator[$i-1]; $denominator[$i] = $denominator[$i-2] + $denominator[$i-1]; } // 获得分数的前n项和 for ($i=0;$i<20;$i++) { $sum += $numerator[$i] / $denominator[$i]; } var_dump($sum);}
【程序11】问题:求1+2!+3!+...+20!的和
1、程序分析:该程序只是把累加变成了累加乘法。
public function actionAddFactorial(){ $n = 20; $sum = 0; for ($i=1;$i<=$n;$i++) { $num = 1; for ($j=1;$j<=$i;$j++) { $num = $j*$num; } $sum += $num; } var_dump($sum);}
【程序12】问题:用递归求5!。
1、程序分析:递归公式:fn=fn_1*4!
public function numFactorial($n){ if($n>1) return $sum = $n * $this->numFactorial($n-1); // 需要注意这点,若是写成函数要替换成函数形式 else return $n;}public function actionNumFactorial(){ $n =4; $sum = $this->numFactorial($n); // 调用上面的阶乘方法(函数)}
[程序13] 标题:有5个人坐在一起,第五个人多大了? 他说他比第四个人大2岁。 当被问及第四人的年龄时,他说自己比第三人大2岁。 问第三个人,说他比第二个人大两岁。 问第二个人,说他比第一个人大两岁。 最后问第一个人,他说他10岁了。 第五个人多大了?
1、程序分析:借助递归,递归分为回溯和递归两个阶段。 如果你想知道第五个人的年龄,你需要知道第三个人的年龄,以此类推,直到第一个人(10岁),然后向前。
public function myAge($n){ if($n == 1) return $age = 10; else return 2 + $this->myAge($n-1);}public function actionMyAge1(){ $n = 5; echo $this->myAge($n);}
【程序14】问题:给定一个不少于5位的正整数,要求是:1.找出它有多少位,2.逆序复制数字。
public function actionIntLength(){ $num = 1232345; $num = (string) $num; $length = strlen($num); $numstring = ''; for ($i=$length-1;$i>=0;$i--) { $numstring .= $num[$i]; } echo $numstring;}
【程序15】标题:一个5位数字,判断是否为回文数。 即12321是回文数,个位和万位相同,十位和千位相同。
public function actionIsPalindromeNumber(){ $num = 12321; $num = (string) $num; if($num[0] == $num[4] && $num[1] == $num[3]) var_dump('Is Palindrome Number'); else echo 'false';}/* * 找到所有的5位的回文数 * */public function actionAllPalindromeNumber(){ $result = []; for ($i=10000;$i<99999;$i++) { $i = (string) $i; if($i[0] == $i[4] && $i[1] == $i[3]) $result[] = $i; } var_dump($result);}