1、一群猴子排成一圈,按1,2,…,n依次編號。然后從第1只開始數,數到第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 = 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
3、楊輝三角
<?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.遍歷一個文件下的所有文件和子文件夾下的文件
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位的正整數,要求:一、求它是幾位數,二、逆序打印出各位數字。
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
