[转]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

 

posted @ 2015-05-10 14:51  todaytoday  阅读(179)  评论(0编辑  收藏  举报