[转]PHP部分常见算法
1. 用户密码六位数,不能大于六位而不能小于六数,数字值正则为[0-9],请用PHP写出有几种可能性,并做暴力破解;
1 function dePassword($pwd) { 2 $tmp = array('000000', '555555', '999999'); 3 for ($i = 0; $i < 3; $i++) { 4 if ($pwd == $tmp[$i]) return $tmp[$i]; 5 } 6 return $pwd < $tmp[1] ? getPwd(0, $pwd, $tmp) : getPwd(1, $pwd, $tmp); 7 } 8 function getPwd($i, $pwd, $tmp) { 9 $half = ceil(($tmp[$i] + $tmp[$i + 1]) / 2); 10 if ($half == $pwd) { 11 return $half; 12 } elseif ($half > $pwd) { 13 return returnI($pwd, $tmp[$i], $half); 14 } else { 15 return returnI($pwd, $half, $tmp[$i + 1]); 16 } 17 } 18 function returnI($pwd, $start, $end){ 19 for ($i = $start + 1; $i < $end; $i++) { 20 if ($i == $pwd) return $i; 21 } 22 } 23 $pwd = '000089'; 24 printf('%06s', dePassword($pwd));
2.牛年求牛:有一母牛,到4岁可生育,每年一头,所生均是一样的母牛,到15岁绝育,不再能生,20岁死亡,问n年后有多少头牛
1 function niunum($n) { 2 static $num = 1; 3 for ($i = 1; $i <= $n; $i++) { 4 if ($i >= 4 && $i < 15) { 5 $num++; 6 niunum($n - $i); 7 } 8 if ($i == 20) $num--; 9 } 10 return $num; 11 } 12 echo niunum(10);
3.合并多个数组,不用array_merge(),思路:遍历每个数组,重新组成一个新数组。
1 function unionArray($a, $b) { 2 $re = array(); 3 foreach ($a as $v) $re[] = $v; 4 foreach ($b as $v) $re[] = $v; 5 return $re; 6 } 7 print_r(unionArray(array(1,2,4,5,'s'), array(2,5,7,'c','d')));
4.二分法查找
思路:以数组中某个值为界,再递归进行查找,直到结束
1 $a = array(1,4,2,5,6,7,0,8,3); 2 function find($arr, $start, $end, $key) { 3 sort($arr); 4 $mid = ceil(($start + $end) / 2); 5 if ($arr[$mid] == $key) { 6 return $mid; 7 } elseif ($arr[$mid] > $key) { 8 return find($arr, $start, $mid - 1, $key); 9 } else { 10 return find($arr, $mid + 1, $end, $key); 11 } 12 } 13 echo find($a, 0, count($a), 2);
5.冒泡排序法
1 function mSort($a) { 2 $len = count($a); 3 for ($i = 0; $i < $len - 1; $i++) { 4 for ($j = $i; $j < $len; $j++) { 5 if ($a[$i] > $a[$j]) { 6 $tmp = $a[$i]; 7 $a[$i] = $a[$j]; 8 $a[$j] = $tmp; 9 } 10 } 11 } 12 return $a; 13 } 14 print_r(mSort($a));
6.杨辉三角
1 $a = array(); 2 for ($i = 0; $i < 6; $i++) { 3 $a[$i][0] = 1; 4 $a[$i][$i] = 1; 5 } 6 for ($i = 2; $i < 6; $i++) { 7 for ($j = 1; $j < $i; $j++) { 8 $a[$i][$j] = $a[$i-1][$j-1] + $a[$i-1][$j]; 9 } 10 } 11 for ($i = 0; $i < 6; $i++) { 12 for ($j = 0; $j <= $i; $j++) { 13 echo $a[$i][$j].' '; 14 } 15 echo '<br/>'; 16 }
7.给两个字符串s1,s2,定义字符串之间的距离d(s1,s2)为通过如下操作使两个字符串一样的最少次数;
1.替换其中一个字符
2.删除一个字符
3.插入一个字符
例如:kooxoo.com与kooxoo.cn的距离为2,12344与1244的距离为1,给出任意两个字符串,求其距离,要求给出算法并分析时间复杂度
方法一:采用levenshtein($str1, $str2)内置函数
1 //1 2 echo levenshtein('kooxoo.com', 'kooxoo.cn'); 3 echo "<br />"; 4 //2 5 function levdis($s,$t){ 6 $n=strlen($s); 7 $m=strlen($t); 8 $matrix=array(range(0,$n+1),range(0,$m+1)); 9 $ret=0; 10 if ($n==0){ 11 return $m; 12 } 13 elseif ($m==0){ 14 return $n; 15 } 16 for ($i=0;$i<=$n;$i++) { 17 $matrix[$i][0]=$i; 18 } 19 for ($j=0;$j<=$m;$j++) { 20 $matrix[0][$j]=$j; 21 } 22 for ($i=1;$i<=$n;$i++) { 23 for ($j=1;$j<=$m;$j++) { 24 if ($s[$i-1]==$t[$j-1]) { 25 $cost=0; 26 }else{ 27 $cost=1; 28 } 29 $matrix[$i][$j]=min($matrix[$i-1][$j]+1, $matrix[$i][$j-1]+1, $matrix[$i-1][$j-1]+$cost); 30 } 31 } 32 return $matrix[$n][$m]; 33 } 34 echo levdis('kooxoo.com', 'kooxoo.cn');
8.把数组array(12,34,56,32) 转化为 array(1,2,3,4,5,6,3,2)
1 function changeArr($arr) { 2 return str_split(implode('', $arr)); 3 } 4 print_r(changeArr(array(12,34,56,32)));
9.把数字1-1亿换成汉字表述,如:123->一百二十三
1 function intToCnstr($intval) { 2 $cnNum = array('零','一','二','三','四','五','六','七','八','九'); 3 $cnUnit = array('','十','百','千','万','亿'); 4 $reCnStr = ''; 5 $intval = intval($intval); 6 if ($intval < 10 && $intval >= 0) { 7 $reCnStr .= $cnNum[$intval]; 8 } elseif ($intval == 1000000000) { 9 $reCnStr .= $cnNum[1].$cnUnit[5]; 10 } elseif ($intval < 0 || $intval > 1000000000) { 11 $reCnStr .= ''; 12 } else { 13 $str = strval($intval); 14 $len = strlen($str); 15 for ($i = 0; $i < $len; $i++) { 16 if (intval($str{$i}) != 0) { 17 $reCnStr .= $cnNum[intval($str{$i})]; 18 $j = $len - 1 - $i; 19 if ($j < 5) { 20 $reCnStr .= $cnUnit[$j]; 21 } elseif ($j >=5 && $j <= 8) { 22 $reCnStr .= $cnUnit[$j - 4]; 23 } 24 } else { 25 if ($i > 0 && $str{$i} != $str{$i - 1}) $reCnStr .= $cnNum[0]; 26 } 27 } 28 } 29 return $reCnStr; 30 } 31 echo intToCnstr(9912016);
10.将一张考试卷的内容,看成一个文本文件,题目形如: 1.1.。。。。。。。(3分)(假设非空行最后字符均为空格)
*要求实现检索出题号及其分值,并输出类似如下的:
*1.1 3分
*1.2 3分
*1.3 5分
1 $txt = <<<EOD 2 1.1请问我们(3分) 3 123234324 4 1.2我们收到收到(4分) 5 适当方式的 6 1.3test(4分) 7 EOD; 8 $match_1 = $match_2 = $match = array(); 9 preg_match_all("//d+/./d/S+/", $txt, $strArr); 10 foreach ($strArr[0] as $k => $v) { 11 preg_match('/^/d+/./d+/', $v, $match_1[$k]); 12 preg_match('//d+分/', $v, $match_2[$k]); 13 } 14 for ($i = 0; $i < count($match_1); $i++) { 15 $match[$i] = $match_1[$i][0].' '.$match_2[$i][0]; 16 } 17 print_r($match);
11.在一组数中,要求插入一个数,按其原来顺序插入,维护原来排序方式。
*思路:找到比要插入数大的那个位置,替换然后把后面的数后移一位。
1 function insertNum($num, $arr) { 2 $len = count($arr); 3 if ($arr[$len - 1] <= $num) { 4 $arr[$len] = $num; 5 return $arr; 6 } 7 for ($i = 0; $i < $len - 1; $i++) { 8 if ($arr[$i] > $num) { 9 $t1 = $arr[$i]; 10 $arr[$i] = $num; 11 for ($j = $i + 1; $j <= $len; $j++) { 12 $t2 = $arr[$j]; 13 $arr[$j] = $t1; 14 $t1 = $t2; 15 } 16 break; 17 } 18 } 19 return $arr; 20 } 21 print_r(insertNum(3, array(1,2,3,4,5)));
12.对一组数进行排序(快速排序算法)。
*思路:通过一趟排序分成两部分,然后递归对这两部分排序,最后合并。
1 function quickSort($arr) { 2 if (count($arr) <= 1) return $arr; 3 $key = $arr[0]; 4 $left = $right = array(); 5 $len = count($arr); 6 for ($i = 1; $i < $len; $i++) { 7 if ($arr[$i] <= $key) $left[] = $arr[$i]; 8 else $right[] = $arr[$i]; 9 } 10 $left = quickSort($left); 11 $right = quickSort($right); 12 return array_merge($left, array($key), $right); 13 } 14 print_r(quickSort(array(1,3,23,5,234,65,6)));
字符:0-9 或 a-z
*长度:1
*那就生成0,1,2,3,4,5,6,7,8,9
*长度:2,就会生成00-99
1 //1 2 function echoStr($len = 1, $type='num') { 3 $str = ''; 4 if ($len < 1) return ; 5 if ($type == 'num') { 6 $ascStart = 48; 7 $ascEnd = 57; 8 } elseif ($type == 'char') { 9 $ascStart = 97; 10 $ascEnd = 122; 11 } else { 12 return ; 13 } 14 for ($i = $ascStart; $i <= $ascEnd; $i++) { 15 for ($j = 1; $j <= $len; $j++) $str .= chr($i); 16 $str .= ','; 17 } 18 return substr($str, 0, -1); 19 } 20 //2 21 function echoStr2($len) { 22 $str = ''; 23 $char = '1234567890qwert!@#$'; 24 $cLen = strlen($char); 25 for ($i = 0; $i < $cLen; $i++) { 26 for ($j = 1; $j <= $len; $j++) { 27 $str .= $char[$i]; 28 } 29 $str .= ','; 30 } 31 return substr($str, 0, -1); 32 } 33 echo echoStr(3, 'num')."<br />"; 34 echo echoStr(2, 'char')."<br />"; 35 echo echoStr2(2);
已知字符串 $string = "2dsjfh87HHfytasjdfldiuuidhfcjh";
*找出 $string 中出现次数最多的所有字符。
1 //1 2 $string = "2dsjfh87HHfytasjdfldiuuidhfcjh"; 3 $re = count_chars($string, 1); 4 print_r(array_map("chr", array_keys($re, max($re)))); 5 echo "<br />"; 6 //2 7 $b = array_count_values(str_split($string)); 8 print_r(array_keys($b, max($b))); 9 //线性表的删除(数组中实现) 10 function delete_array_element($array, $i) { 11 $len = count($array); 12 for ($j=$i; $j<$len; $j++){ 13 $array[$j] = $array[$j+1]; 14 } 15 array_pop($array); //删除最后空元素 16 return $array; 17 } 18 print_r(delete_array_element(array(1,2,3,4,5), 2));
转载自:http://blog.csdn.net/caleng/article/details/5276403