一、一羣猴子排成一圈,按1,2,…,n依次編號。而後從第1只開始數,數到第m只,把它踢出圈,從它後面再開始數,再數到第m只,在把它踢出去…,如此不停的進行下去,直到最後只剩下一隻猴子爲止,那隻猴子就叫作大王。要求編程模擬此過程,輸入m、n, 輸出最後那個大王的編號。php
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);
二、有一母牛,到4歲可生育,每一年一頭,所生均是同樣的母牛,到15歲絕育,再也不能生,20歲死亡,問n年後有多少頭牛。html
function niu($y) { static $num = 0; //定義靜態變量;初始化牛的數量爲0 for ($i = 1; $i <= $y; $i++) { if ($i >= 4 && $i < 15) { //每一年遞增來算,4歲開始+1,15歲不能生育 $num++; } else if ($i == 20) { return $num; //20歲死亡 } } return $num; } echo niu(20);//11
三、楊輝三角算法
<?php /* 默認輸出十行,用T(值)的形式可改變輸出行數 */ class T{ private $num; public function __construct($var=10) { if ($var<3) die("值過小啦!"); $this->num=$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 "<br/>"; 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"<br/>"; } } } $yh=new T('3'); //$yh=new T(數量); $yh->display(); ?>
4.冒泡排序編程
function maopao($arr){ $len = count($arr); for($k=0;$k<=$len;$k++) { for($j=$len-1;$j>$k;$j--){ if($arr[$j]<$arr[$j-1]){ $temp = $arr[$j]; $arr[$j] = $arr[$j-1]; $arr[$j-1] = $temp; } } } return $arr; }
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<$length; $i++) { if($base_num > $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.二分查找算法(折半查找算法)函數
function binsearch($x,$a){ $c=count($a); $lower=0; $high=$c-1; while($lower<=$high){ $middle=intval(($lower+$high)/2); if($a[$middle]>$x){ $high=$middle-1; } elseif($a[$middle]<$x){ $lower=$middle+1; } else{ return $middle; } } return false; }
7.PHP奇異算法 學習
<?php function test(){ $a=1; $b=&$a; echo (++$a)+(++$a); } test();
PHP7如下的版本返回的是 6,PHP7版本返回5 測試
8.字符集合:輸入一個字符串,求出該字符串包含的字符集合,並按順序排序(英文)優化
function set($str){ //轉化爲數組 $arr = str_split($str); //去除重複 $arr = array_flip(array_flip($arr)); //排序 sort($arr); //返回字符串 return implode('', $arr); }
9.遍歷一個文件下的全部文件和子文件夾下的文件ui
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級,或者邁3次1級總共3中方式
function jieti($num){ //其實是斐波那契數列 return $num<2?1:jieti($num-1)+jieti($num-2); }
12.請寫一段PHP代碼,確保多個進程同時寫入同一個文件成功
<?php $fp = fopen("lock.txt","w+"); if (flock($fp,LOCK_EX)) { //得到寫鎖,寫數據 fwrite($fp, "write something"); // 解除鎖定 flock($fp, LOCK_UN); } else { echo "file is locking..."; } fclose($fp); ?>
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<=$high){ $middle=intval(($lower+$high)/2); if($a[$middle]>=$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 的字符開始的長度爲 l 的一個子串。你要將這個子串左右翻轉後插在這個子串原來位置的正後方,求最後獲得的字符串是什麼。字符串的下標是從 0 開始的,你能夠從樣例中獲得更多信息。
每組測試用例僅包含一組數據,每組數據第一行爲原字符串,長度不超過 10 ,僅包含大小寫字符與數字。接下來會有一個數字 n 表示有 n 個操做,再接下來有 n 行,每行兩個整數,表示每次操做的(p , l)。
保證輸入的操做必定合法,最後獲得的字符串長度不超過 1000。
<?php class TestKeenSting{ private $str; public function __construct($str) { $this->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;$i<$times;$i++) { $t = $str[$len-1-$i]; $str[$len-1-$i] = $str[$i]; $str[$i] = $t; } return $str; } } $a = new TestKeenSting('ab'); $re = $a->run([[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
<?php class TestKeenSting{ private $song_num; private $song_size; private $cd_size; public function __construct($n,$s,$l) { if($n>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實現一個雙向隊列
<?php class Deque{ private $queue=array(); public function addFirst($item){ return array_unshift($this->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 請使用冒泡排序法對如下一組數據進行排序10 2 36 14 10 25 23 85 99 45。
<?php // 冒泡排序 function bubble_sort(&$arr){ for ($i=0,$len=count($arr); $i < $len; $i++) { for ($j=1; $j < $len-$i; $j++) { if ($arr[$j-1] > $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 < $high && $arr[$high] >= $pivotkey){ $high--; } $temp = $arr[$low]; $arr[$low] = $arr[$high]; $arr[$high] = $temp; while($low < $high && $arr[$low] <= $pivotkey){ $low++; } $temp=$arr[$low]; $arr[$low]=$arr[$high]; $arr[$high]=$temp; } return$low; } function quick_sort(&$arr,$low,$high){ if($low < $high){ $pivot = partition($arr,$low,$high); quick_sort($arr,$low,$pivot-1); quick_sort($arr,$pivot+1,$high); } } ?>
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 < $card_num;$i++){ $index = rand(0,$card_num-$i-1); $cards[$i] = $tmp[$index]; unset($tmp[$index]); $tmp = array_values($tmp); } return $cards; } // 測試: print_r(wash_card($card_num)); ?>
【程序1】 題目:古典問題:有一對兔子,從出生後第3個月起每月都生一對兔子,小兔子長到第四個月後每月又生一對兔子,假如兔子都不死,問每月的兔子總數爲多少?
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) return false; for ($i=2;$i<=$n+1;$i++) { $arr[$i] = $arr[$i-1] + $arr[$i-2]; } var_dump($arr); echo $arr[$n+1]; }
【程序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 %100 ) / 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 <0 || $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<$n;$i++) { $num = 0; for ($j = 0;$j<=$i;$j++) { $num += $a* pow(10,$j); } $sum += $num; } var_dump($sum); }
【程序6】題目:一個整數,它加上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&&$year%100!=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,z,請把這三個數由小到大輸出。
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<$x { $x = $x+$y; $y = $x-$y; $x = $x-$y; } if($x>$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 "<br>"; } }
【程序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我的坐在一塊兒,問第五我的多少歲?他說比第4我的大2歲。問第4我的歲數,他說比第3我的大2歲。問第三我的,又說比第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); }
連接:http://www.cnblogs.com/Survivalist/p/8119891.html