PHP基础4--函数-数组
主要
- 函数
- 数组
- 常用系统函数
函数
基础
1)定义
1 function 函数名(【$形参1】,【$形参2】,.....) { 2 //函数体 3 }
2) 调用
函数名([$实参1][,$实参2]....) ; //一般要与定义中形参一一对应,个数一致
3)调用过程
step 1: 将函数调用的实参数据,传递给函数的形参 step 2: 程序进入到函数内部 step 3: 在函数内部,按正常的流程顺序执行里面的代码 step 4: 如果函数结束或遇到return,返回到原来调用函数的位置,继续执行后续的代码
函数的参数
1)形参的默认值
定义函数时,可以赋一个默认值。 如 function add($x=100, $y=200) {.....} 形参$x,$y设置默认值
如果是部分形参设置默认值,则设置默认值的形参必须放在后边。 如 function f($a, $b, $c=4){.....} 函数中$c
2)形参传值
实参变量传值给形参变量。两种传值方式
值传递: 默认。一般参数传值都是值传递
引用传递: 需要在形参前面加 “&”符号。 如 function f($a, &$b){....} 中 $b就是引用传递
3) 参数的数量
一般实参数量与形参数量一致。当形参有默认值,可以省略有默认值的实参。但只能从右边往左省略
特殊情形: 不定义形参,实参任意给出。 如 系统函数 var_dump($v1,$v2,...)
依赖于3个系统函数:
func_get_args() : 获取实参列表,存入数组。 结果返回一个包含实参列表的数组
func_get_args($i) : 获取第 $i 个实参数据。 $I 从0开始, 返回实参列表的指定项
func_num_args(): 获取实参的数量(个数)
函数的返回值
可以返回数据,也可以不返回
返回数据: return 数据或变量
不返回数据: 没有return语句,或有 return 但其后面不接任何数据
函数中遇到return语句,自动终止函数的执行,返回到调用函数的位置继续执行后续代码
函数的形式
1) 常规形式 如 function f(..) {...}
2) 可变函数
可变变量: 如 $a= "b"; $b=2; echo $$a; //2
可变函数:函数名是一个变量。 如: function f() {.....} $v = "f"; $v();//可变函数 $v() 既 f()
1 <?php 2 3 //可变函数 4 //声明了三个函数 5 function jpg() { echo "<br /> 这是jpg图片<br />"; } 6 function png() { echo "<br /> 这是png图片<br />"; } 7 function gif() { echo "<br /> 这是gif图片<br />"; } 8 9 //模拟上传的文件名 10 $file = "abc.1.2.png"; //用户上传的图片 其后缀可能是png,jpg,gif等 11 12 //strrchr(字符串,指定字符) : 查找指定字符在字符串中最后一次出现直到结尾(包含指定字符) 13 $postfix = strrchr($file,"."); //获取字符串$file中最后一次出现的“.”之后的所有字符串(包含.) 14 echo $postfix; //结果 .png 15 16 //substr(字符串,开始位置[,长度]) : 返回字符串从开始位置到指定长度的子字符串 17 $postfix = substr($postfix,1); //获得该字符串从位置1开始之后的所有字符串 既 png 18 $postfix(); //可变函数 调用png()
3) 匿名函数
匿名函数: 没有名字的函数。有两种形式的匿名函数
形式1: 将一个匿名函数 赋值 给一个变量。 该变量就代表该匿名函数
如:$var = function() { //函数体 }; $var(); //调用匿名函数,类似可变函数
形式2: 将匿名函数作为 “实参” 来使用
function add($x,$y,$z){ $sum = $x + $y; $diff = $x-$y; $z( $sum,$diff); //可变函数 } //调用add函数 add(8,5, function($x,$y){ echo "x=$x, y=$y"; //x=13 , y=3 });
作用域
php中变量的作用域有3个:
1) 局部作用域: 函数内部的变量
2) 全局作用域: 对所有代码范围。 系统预定的超全局数组,如 $_GET, $_POST, $_COOKIE,....
3) 超全局作用域: 函数外部的变量
访问限制:
1) 局部范围 不能访问 全局变量
1 $v1 = 1; //全局变量 2 function f1() { 3 echo "<br />在函数内部访问外部:v1 =".$v1; //局部范围不能访问全局变量 4 } 5 f1(); //报错 Notice: Undefined variable: v1
2)全局范围 不能访问 局部作用域的变量
函数内部的变量,通常调用结束,就被销毁了
1 //2-全局范围不能访问局部变量 2 function f2() { 3 $v2 = 1; //局部变量 4 return $v2; 5 } 6 $res = f2(); 7 echo "在函数外部访问局部变量:v2 =".$v2; //Notice: Undefined variable: v2
3) 特殊的局部变量: 静态变量
局部范围中静态变量:函数调用后一直存在。
在函数内部赋予初值,只会执行一次(赋值语句只执行一次)。
1 <?php 2 /** 3 * 函数中的静态变量特点: 4 * 1.函数调用结束不会被销毁 5 * 2.不管调用几次,函数中的静态变量的赋初值只执行1次,后面的调用会使用函数上次的值 6 */ 7 function f () { 8 static $c = 0; //静态局部变量, 值会保留 9 $c++; //此数据会持续保留 10 $d = 0; //普通局部变量,调用结束就会销毁 11 $d++; 12 echo "<br />c = $c, d = $d "; 13 echo "<br />此函数调用的次数: $c"; 14 } 15 f(); 16 f(); 17 f(); //d值永远不变是1,$c每次调用累加
4) 局部范围 使用 全局变量 方法
方式1: 使用global关键字
1 /** 2 * 在局部环境使用全局变量有2种方式: 3 * 方式1: global 全局变量名同名的变量 4 * 方式2: $GLOBALS['全局变量名'] 5 * 两者有细微的区别: $GLOBALS指代的就是全局变量, 6 * 而用global声明的,相当于在函数内部声明了一个同名变量,指向全局变量值的地址,如果unset,只是删除了引用 7 */ 8 9 //方式1: global 全局变量名同名的变量 10 $v4 = 4; //全局变量 11 function f4() { 12 //在函数中使用global来声明一个要使用的全局变量的同名局部变量 13 global $v4; //$v4是局部变量,只是跟全局的$v4同名 14 //实际情况是: 此时外部v4变量跟内部的v4变量, 15 //共同指向一个数据区--引用关系 16 echo "<br />在局部访问全局变量v4 = ".$v4; //4 可以直接调用了 17 $v4 = 100; //改变全局变量的值 18 unset($v4); //释放函数内部的引用,实际全局变量仍然存在 19 } 20 f4(); 21 echo "<br />在全局再次访问v4=".$v4; //在函数内部被改变了 22 echo "<hr />";
方式2: 使用超全局数组变量$GLOBALS
如果对$GLOBALS变量的某个单元进行unset. 如 unset($GLOBALS['var']); 则其对应销毁该变量($var)
1 //方式2: $GLOBALS['全局变量名'] 2 //使用$GLOBALS超全局变量 3 $v5 = 4; //全局变量 4 function f() { 5 echo "在局部访问全局变量v5 = ".$GLOBALS["v5"]; //在局部访问全局变量v5 = 4 6 $GLOBALS["v5"] = 100; 7 } 8 f(); 9 echo "<br />在全局再次访问v5=".$v5; //v5=100 10 echo "<br />在全局再次访问v5=".$GLOBALS["v5"]; //v5=100
函数编程思想
递归思想
递归(迭代)函数: 在函数内部调用自己的函数
1 function recursion($n) { 2 if(最小一级){ return 已知的答案 } 3 $result = 对recursion($n-1)进行简单运算 4 return $result; 5 }
递推思想
前一个答案,推出后一个答案
1 <?php 2 3 // 求5的阶乘 4 //1-初步 5 $recursion1 = 1; //表示1的阶乘(已知) 6 $recursion2 = $recursion1 * 2; //2的阶乘 7 $recursion3 = $recursion2 * 3; //3的阶乘 8 $recursion4 = $recursion3 * 4; //4的阶乘 9 $recursion5 = $recursion4 * 5; //5的阶乘 10 11 //2-使用一个变量实现 12 $recursion = 1; //表示1的阶乘(已知) 13 $recursion = $recursion * 2; //2的阶乘 14 $recursion = $recursion * 3; //3的阶乘 15 $recursion = $recursion * 4; //4的阶乘 16 $recursion = $recursion * 5; //5的阶乘 17 18 //3-上述递推的规律 19 $recursion = 1;//表示1的阶乘(已知) 20 for($i=2; $i<=5;++$i){ 21 $recursion = $recursion * $i; 22 } 23 24 //4-通过上述思路,进一步转换 ==》 前一个答案,推出后一个答案 25 $pre = 1; //前一个已知的答案: 这是第一个,1的阶乘 26 for($i = 2; $i <= 5; ++$i) { //意图求得从2到5的“每一个阶乘” 27 $next = $pre * $i; //要求的结果是“前一个结果”经过简单乘法运算而得到 28 echo "<br />{$i}的阶乘是{$next}"; 29 $pre = $next; //将当前求得的“结果”,又当成“前一个”,以供下一次使用 30 } 31 echo "<br />结果为: ".$next;
既能使用递归算法解决,又能使用递推算法解决,则因该使用递推算法
1 <?php 2 /* 数列 1,1,2,3,5,8,13,…… 3 说明: 4 第1项是1,第2项是1 (都是已知) 5 其他项,是其前两项的和 6 求: 第20项: 7 */ 8 //1-递推规律 9 $pre1 = $pre2 = 1; 10 $result = $pre1 + $pre2; //第3项 = 第1项 + 第2项 11 $pre1 = $pre2; 12 $pre2 = $result; 13 $result = $pre1 + $pre2; //第4项= 第2项 + 第3项 14 $pre1 = $pre2; 15 $pre2 = $result; 16 $result = $pre1 + $pre2; //第5项= 第3项 + 第4项 17 18 //根据上述规律简化 19 $t1 = microtime(true); 20 $pre1 = 1; 21 $pre2 = 1; 22 for($i = 3; $i <= 20; $i++){ 23 $result = $pre1 + $pre2; 24 $pre1 = $pre2; 25 $pre2 = $result; 26 } 27 echo $result; 28 $t2 = microtime(true); 29 echo "<br/>采用递推思想实现耗时:".($t2-$t1); 30 31 /**递归思想实现**/ 32 echo "<hr>"; 33 function shulie($n) { 34 if(($n == 2) || ($n == 1)) { 35 return 1; 36 } 37 $result = shulie($n-2) + shulie($n-1); 38 return $result; 39 } 40 $t1 = microtime(true); 41 $v1 = shulie(20); 42 echo $v1; 43 $t2 = microtime(true); 44 echo "<br/>采用递归思想实现耗时:".($t2-$t1);
数组
基础
1) PHP中的数组单元的顺序,与下标无关, 是由其放入的顺序决定。
2) 定义赋值:
不写下标,则使用默认下标, 从0开始的整数 如: $arr = array(1,3,5,7);
关联数组,下标是字符串。 如: $arr("a"=>3, "b"=>4);
下标: 可以任意设定,可以是数字和字符串混合使用。 如果下标重复,后面覆盖前面
可以指定下标,不指定则会采用自动下标。
自动下标: 其值为之前所有用过的整数下标的最大值+1
数组内最后一个逗号可有可无。 如 $arr = array(1,2,3,);
非常规情况的下标的自动转换:7.7 = > 7 true => 1 false => 0
3) 数组的取值: 如 $val = $arr[1];
4) 数组的分类:
按健值分:索引数组, 关联数组, 混合数组
按数组的维度分:一维,二维,.....
如:$a = array( array(1,2,3), array(4,5,6));
5) 使用
1 <?php 2 /** 3 * 求一个一维数组的平均值: 总和/长度 4 */ 5 $arr = array(1,11,111,1111); 6 $len = count($arr); //数组的长度 7 $sum = 0; //用于存储总和 8 for($i = 0; $i < $len; ++$i) { 9 $sum += $arr[$i]; 10 } 11 echo "<br />平均值为: ".($sum/$len); //平均值为: 308.5
1 /** 2 * 求一个二维数组的平均值: 首先变为一维数组,再求和 3 */ 4 $arr = array( array(1,11,111), 5 array(2,22,222,2222), 6 array(3,33,333,3333,33333) 7 ); 8 $len = count($arr); // 二维数组的长度 其实就是行数 9 $sum = 0; //用于存储总和 10 $c = 0; //计数 11 for($i = 0; $i < $len; ++$i) { 12 $temp = array(); 13 $temp = $arr[$i]; //存储一维数组 14 $len_temp = count($temp); 15 for($j = 0; $j < $len_temp; ++$j) { 16 $sum += $temp[$j]; //累加 17 ++$c; //计数 18 } 19 } 20 echo "<br />平均值为: ".($sum/$c); //平均值为: 3302.1666666667
1 <?php 2 /** 3 * 求一个一维数组的最大值: 先假设第一个数组元素是最大值,然后逐个比较得到最大值 4 */ 5 $arr = array(13,8,5,11,22,2); 6 $max = $arr[0]; //将第一项放入$max中,用该变量来存储数组中的最大值 7 $key = 0; //存储最大值的下标 8 $len = count($arr); //数组长度 9 for($i = 0; $i < $len; ++$i) { 10 if($arr[$i] > $max) { 11 $max = $arr[$i]; 12 $key = $i; 13 } 14 } 15 echo "<br />最大值为: ".$max." 最大下标是: ".$key;
1 <?php 2 /** 3 * 求交换一个一维数组的最大值和最小值的位置 4 * 假设第一个数组元素是最大值==》得到值$max和下标$maxIndex 5 * 假设第一个数组元素是最小值==》得到值$min和下标$minIndex 6 * 循环比较,只要比$max大的值,就将大值放到$max中。最小值也是同样形式的处理 7 * 此时就可以得到最大值,最小值及对应索引,交换位置则只需要一个临时变量就可以实现 8 */ 9 $arr = array(13,8,5,11,22,2); 10 echo "<br />交换之前: "; 11 print_r($arr); 12 $max = $arr[0]; //将第一项放入$max中,用该变量来存储数组中的最大值 13 $key_max = 0; //存储最大值的下标 14 $min = $arr[0]; //存储数组最小值 15 $key_min = 0; //最小值对应的健值 16 $len = count($arr); //数组长度 17 for($i = 0; $i < $len; ++$i) { 18 if($arr[$i] > $max) { 19 $max = $arr[$i]; 20 $key_max = $i; 21 } 22 if($arr[$i] < $min) { 23 $min = $arr[$i]; 24 $key_min = $i; 25 } 26 } 27 echo "<br />最大值为: ".$max." 最大下标是: ".$key_max; 28 echo "<br />最小值为: ".$min." 最大下标是: ".$key_min; 29 echo "<br />交换之后: "; 30 $tmp = $arr[$key_max]; 31 $arr[$key_max] = $arr[$key_min]; 32 $arr[$key_min] = $tmp; 33 print_r($arr);
遍历数组
foreach 遍历数组
1) foreach中可以使用break 和 continue
2) 遍历过程中 值变量 默认的传值方式: 值传递
3)遍历过程也可以使用引用传递。 如 foreac($arr as $key=> & $value){....}
$key不能使用引用方式
4) foreach 默认是在原数组上进行遍历。 如果遍历过程中对数组进行了某种修改或某种指针性操作,则会复制数组后在复制的数组上继续遍历循环(原数组保持不变)
5) foreach中如果值变量是引用传递, 则都是在原数组上进行遍历
1 foreach($数组变量名 as [$key =>]$value ) { 2 //循环体; 这里可以去使用$key 和 $value 3 //$key 和 $value 就是该遍历语句一次次取得的该数组的每一个单元(项)的下标和对应值。 4 //且,它总是从数组的开头往后顺序取数据 5 }
1 /** 2 * foreach遍历流程 3 */ 4 $arr = array(1=>3, 'a1'=>11, 3=>5, 'mn'=>18, 88=>2); 5 foreach($arr as $key => $value) { 6 echo "<br/>".$key."=>".$value; 7 } 8 //遍历完成后,此时数组指针位置---超出数组范围 9 $end_key = key($arr); 10 $end_value = current($arr); 11 echo "<br />此时end_key(键)为: ";var_dump($end_key); // null 12 echo "<br />此时end_value(值)为: ";var_dump($end_value); //bool值 false
<?php //在foreach循环中,”修改数组“--修改不影响遍历的”本来过程“ $arr = array(1=>3, 'a1'=>11, 3=>5, 'mn'=>18, 88=>2); foreach($arr as $key => $value) { echo "<br /> $key : $value"; if($key === 3) { $arr[99] = "新的数据项"; //循环进入此时,对该数组添加了一项,而且是添加到数组的末尾 } } echo "<br />此时,数组新的项已经添加进去了 <br />"; print_r($arr); $value = current($arr); //指向'mn'=>18 $key = key($arr); echo "<br /> 此时数组指针指向的单元为: $key => $value"; //'mn'=>18 echo "<hr/>"; //在foreach使用引用传递,则是在原数组上进行 //值变量使用”引用传递“ 则无论如何都是在原数组中进行 $arr = array(1=>3, 'a1'=>11, 3=>5, 'mn'=>18, 88=>2); foreach($arr as $key => &$value) { echo "<br /> $key : $value"; if($key === 3) { //使用的引用传递,所以也会遍历出来 $arr[99] = "新的数据项"; //循环进入此时,对该数组添加了一项,而且是添加到数组的末尾 } } echo "<br />遍历后也能看出来: <br />"; print_r($arr); $value = current($arr); $key = key($arr); echo "<br /> 此时数组指针指向的单元为: $key => $value";
for+next()遍历数组
对PHP数组,往往不能单纯使用for循环进行遍历。
for循环只能循环"下标为连续的整数的数组"
1 <?php 2 /** 3 * for+next遍历数组 4 */ 5 //使用for循环和next函数,遍历以下数组 6 $arr = array(1=>3, 'a1'=>11, 3=>5, 'mn'=>18, 88=>2); 7 for($i = 0; $i < count($arr); ++$i) { //控制循环次数 8 $key = key($arr); //取得当前的键 9 $value = current($arr); //取得当前的值 10 echo "<br /> $key => $value "; 11 next($arr); //数据处理完毕后,将数组指针后移动一位 12 } 13 //如果只使用for,则只能针对连续的索引数组有效
while+each()+list() 遍历数组
each(): 先取得一个数组的”当前单元”的下标和值(并放入一个数组),然后将指针移动到下一个单元
list(): 用于一次性取得一个数组中从0开始的数字下标的多个单元的值!
形式: list($变量1,$变量2, $变量3, .....) = $数组
作用:上述代码想当于 $变量1 = $数组[0];$变量2 = $数组[1];$变量3 = $数组[2];..........
注意: 变量的个数,要跟该数组的数字下标的单元对应,如果某个变量对应的该数组下标不存在,就会报错
<?php /** * each()函数理解 * 获得的结果是: 0,1索引 key,value关联 */ //each的含义和使用方法 $arr = array(1 => 3, 'a1' => 11, 3 => 5 ); $result = each($arr); //取得 1=>3这项, 结果是一个数组 /** * Array ( * [1] => 3 * [value] => 3 * [0] => 1 * [key] => 1 * ) */ echo "<br />result为: "; print_r($result); $result2 = each($arr); //取得 a1=>11这项, 结果是一个数组 echo "<br />result为: "; print_r($result2);
1 <?php 2 /** 3 * list()函数理解 4 * 5 */ 6 //list()函数 7 $c = array(0=>0, 1=>11, 3=>33, 2=>22); 8 9 //获得数组第0项的值 10 list($v1) = $c; //将数组下标为0的项赋值给v1 11 echo "<br />v1 = $v1"; //v1 = 0 12 13 //获得数组第0,1项的值 14 list($s1,$s2) = $c; //将数组下标为0,1的项赋值给s1,s2 15 echo "<br />s1 = $s1, s2 = $s2"; //s1 = 0, s2 = 11 16 17 //获得数组第0,1,2项的值 18 list($m1,$m2,$m3) = $c; //将数组下标为0,1,2的项赋值给m1,m2,m3 19 echo "<br />m1 = $m1, m2 = $m2, m3 = $m3"; //m1 = 0, m2 = 11, m3 = 22
1 <?php 2 /** 3 * list()函数理解 4 * 下面数组中没有索引为1的数组元素,使用list取出2个值时会报错 5 */ 6 //list()函数 7 8 $arr = array('value'=>5, 0=>1, 'key'=>1); //此时该数组中没有下标1的数组元素 9 10 //Notice: Undefined offset: 1 11 list($key, $value) = $arr; //分别取得下标为0,1的数据 下标为1的是没有的 12 13 echo "<br />key = $key, value = $value"; // key = 1, value =
1 <?php 2 /** 3 * while+each+list 遍历数组 4 */ 5 //while+each+list方式遍历 6 //根据list只能遍历索引数组的特点,使用each取出数组的值,each既能得到数组元素每一项的关联数组也能得到索引数组 7 $arr = array(1=>3, 'a1'=>11, 3=>5, 'mn'=>18, 88=>2); 8 while(list($key,$value) = each($arr)) { //模式化的写法 9 echo $key,"=>".$value."<br/>"; //输出 1=>3, a1=>11, 3=>5, mn=>18, 88=>2 10 }
排序
1) sort(): 值排序,键重新索引
2) asort(): 值排序,键保留
<?php header("Content-type:text/html;charset=utf-8"); /** * 数组排序 * sort($arr): 对数组排序 * bool sort ( array &$array [, int $sort_flags = SORT_REGULAR ] ) * 数组单元按升序排序 * 参数2: 排序类型标记,可以设置作为数值或字符串进行比较 * 注意:此函数为 array 中的元素赋与新的键名。这将删除原有的键名,而不是仅仅将键名重新排序。 * asort: 对数组进行排序并保持索引关系 * bool asort ( array &$array [, int $sort_flags = SORT_REGULAR ] ) * */ //sort排序 //值是排序了,但健值却丢了 $arr = array(1=>3, 'a1'=>11, 3=>5, 'mn'=>18, 88=>2); echo "<br />排序前; "; print_r($arr); sort($arr); echo "<br />排序后; "; print_r($arr); //asort排序 //值排序,健值保留 $arr = array(1=>3, 'a1'=>11, 3=>5, 'mn'=>18, 88=>2); echo "<br />排序前; "; print_r($arr); asort($arr); echo "<br />排序后; "; print_r($arr);
数组操作算法
冒泡排序
冒泡排序算法: 一趟趟从左往右进行相邻单元的两两比较,凡是2个元素的顺序不是目标顺序,就将他们进行交换。
1) 从数组的左边开始,依次两两比较相邻的2个数据的大小。 2) 如果发现左边的比右边的大,则将他们进行交换。 3) 这样进行”一趟“之后,必然可以确定最大的一个数据放在最右边 4) 按此方式”对剩余数据“继续进行下一趟,则会确定这些剩余数据的最大值放在剩余位置的最右边
1 <?php 2 header("Content-type:text/html;charset=utf-8"); 3 /** 4 * 冒泡排序算法 5 * 思路: 6 * 从数组的左边开始,依次相邻两两元素比较,左边大则交换位置,一趟下来,最大值到了最右边 7 * 剩下数据按上述方式继续比较 8 * 9 * 规律总结:( 如假设: $arr= (4,3,1,5);) 10 * $arr的长度为n(数组有n个元素) ---此时有4个元素 11 * 比较的趟数: n-1趟 ---比较3趟 12 * 每一趟比上一趟数据少一个。第一趟比较次数: n-1次 ---第一次比较3次 13 * 左边大于右边则进行位置交换 14 */ 15 //冒泡法排序: 16 $arr = array(9,3,5,8,2,7); //长度是6 ==》 比较的趟数是5,比较的次数:5,4,3,2,1 既$len-1-$i 17 echo "<br />排序之前: "; print_r($arr); 18 $len = count($arr); //统计数组的长度 19 for($i = 0; $i < $len -1; ++$i) { //比较的趟数 20 for($j = 0; $j < $len -1 - $i; ++$j) { //每趟比较的次数 $j当作下标使用 21 if($arr[$j] > $arr[$j + 1]) { 22 //进行交换 23 $t = $arr[$j]; 24 $arr[$j] = $arr[$j + 1]; 25 $arr[$j + 1] = $t ; 26 } 27 } 28 } 29 echo "<br />排序之后: "; print_r($arr); 30 /** 31 * for($i = 0; $i < 5; ++$i) //趟数 32 * for($j = 0; $j < 5 - $i; ++$j) //每一趟比较的次数 33 * if($arr[$j] > $arr[$j + 1]) {..} 34 * 第1趟: 9,3,5,8,2,7 =》 3,5,8,2,7,9 35 * 第2趟 3,5,8,2,7,9 =》 3,5,2,7,8,9 36 * 第3趟 3,5,2,7,8,9 =》 3,5,2,7,8,9 37 * 第4趟 3,5,2,7,8,9 =》 3,2,5,7,8,9 38 * 第5趟 3,2,5,7,8,9 =》 2,3,5,7,8,9 39 */
选择排序
选择排序:一趟趟从“现有剩余数据”中找出最大的单元,并每一趟之后将该单元,跟这一趟中 最后一个单元进行交换。
1 1, 求得一个数组的最大值的下标,并将这个最大值下标的单元跟最后一个单元进行交换 2 2,继续从剩余数据中取得最最大值的下标,并将这个最大值下标的单元跟剩余的最后一个单元交换,以此类推,直到只剩一个数据,就不用找了
<?php header("Content-type:text/html;charset=utf-8"); /** * 选择排序算法 * 思路: * 找到所有数组元素中的最大值,与最后一个元素位置进行交换--确定最后一个元素 * 除最后一个元素找剩下的所有元素的最大值,与此时的最后一个元素位置交换(既数组倒数第2个元素) * 至到最后一个元素后就结束了 * 规律总结:( 如假设: $arr= (4,3,1,5);) * $arr的长度为n(数组有n个元素) ---此时有4个元素 * 第1趟得到最大值,第2趟得到次大值,。。总共的趟数: n-1 ---此时应进行3趟 * 每趟找最大值,后一趟会少一个值。第1趟数据是n个,第2趟数据是n-1,... 第i趟 :n-i * 每次找到的最大值进行交换位置 */ //选择排序 $arr = array(9,3,5,8,2,7); echo "<br />排序之前: "; print_r($arr); $len = count($arr); //统计数组的长度 for($i = 0; $i < $len -1; ++$i) { //比较的趟数 //每一趟开始找最大值 $max = $arr[0]; //找最大值的下标,要取得第1项的值 $key = 0; // 最大值的下标,也要先取得第一项的下标 for($j = 0; $j < $len - $i; ++$j) { //找到最大值, k也可以理解为下标 if($max < $arr[$j]) { $max = $arr[$j]; $key = $j; } } //前面一定可以获得最大值及其所在的下标:即最大值单元 // 然后开始进行交换 $t = $arr[$key]; $arr[$key] = $arr[$len-1-$i]; //$len-1-$i 表示最后一个单元 $arr[$len-1-$i] = $t; } echo "<br />排序之后: "; print_r($arr); /** * for($i = 0; $i < 5; ++$i) //趟数 * $max = $arr[0]; * $key = 0; * for($j = 0; $j < 5 - $i; ++$j) //每一趟比较的次数 * if($max < $arr[$j]) {..} * 第1趟: 9,3,5,8,2,7 =》 7,3,5,8,2,9 * 第2趟 7,3,5,8,2,9 =》 7,3,5,2,8,9 * 第3趟 7,3,5,2,8,9 =》 2,3,5,7,8,9 * 第4趟 2,3,5,7,8,9 =》 2,3,5,7,8,9 * 第5趟 2,3,5,7,8,9 =》 2,3,5,7,8,9 */
二分查找
二分查找算法的前提: 针对的是索引数组;针对的是已经排好序的数组
1000个数据,约10次找出 100万个数据,约20次找出 10亿个数据,约30次找出 40亿个数据,约32次找出
1 <?php 2 /** 3 * 需求: 请找出该数组中是否有22? 4 * 二分查找前提: 针对索引数组,且是排好序的数组 5 */ 6 //二分查找算法 7 $arr = array(1,3,11,18,19,22,25,33,34,38,44,55,56,58,60,61,66,70,77,88,90,91,93,95,98); 8 $search = 22; //要找的数据 9 $len = count($arr); //数组的长度,最大下标为len-1 10 $c2 = 0; //计数 11 12 //函数功能: 从数组$arr中的位置$begin开始到位置$end之间找数据$target 13 function binary_search($arr,$target,$begin,$end) { 14 $GLOBALS['c2']++; 15 if($end < $begin) { return false; } 16 $midKey = floor(($begin + $end)/2); //定位中间的位置 17 $midValue = $arr[$midKey]; //取得中间项值 18 19 if($midValue == $target) { //找的值恰好就是中间的那个 20 return true; 21 } else if($midValue > $target) { //中间项要比找的$target大,就去左边找 22 $result = binary_search($arr,$target,$begin,$midKey - 1); 23 } else { //中间项要比找的$target小,就去右边找 24 $result = binary_search($arr,$target,$midKey + 1,$end); 25 } 26 return $result; 27 } 28 29 //使用binary_search()函数从$arr中的0到$len-1位置找$search 30 $v2 = binary_search($arr, $search, 0, $len -1); 31 echo "结果是: "; var_dump($v2); //bool(true) 32 echo "<br>查询次数:".$c2; //2
常用系统函数
字符串函数
1)字符串截取
strrch() substr() strchr()
strrchr($str,$char) : 查找指定字符$char在 字符串$str 中最后一次出现直至结尾(包含指定字符) substr($str,$start[,$length]) : 返回字符串$str 从开始位置$start 到指定长度$length的子字符串 strchr() 查找字符串的首次出现 别名: strstr
2) 输出与格式化
echo , print, printf, print_r, var_dump
3) 字符串去除与填充
trim() ltrim() rtrim() str_pad()
trim() 去除两边的空白 ltrim() 去除左边的空白 rtrim() 去除右边的空白 str_pad($str, $length, $str2, $location) 将指定字符串$str, 用字符串 $str2填充到指定的长度$length, 可以指定填充的位置; $location表示填充的方向,左边填充或右边填充。取值: STR_PAD_RIGHT , STR_PAD_LEFT, STR_PAD_BOTH
4)字符串连接与分割
implode(), join(), explode(), str_split()
5) 字符串替换
str_replace() 子字符串替换
substr_replace() 替换字符串的子串
6) 字符串长度与位置
strlen()
strpos() 查找字符串首次出现的位置
strrpos() 查找指定字符串在目标字符串中最后一次出现的位置
7) 字符串转换
strtolower() strtoupper() lcfirst() ucfirst() ucwords()
strtolower() 转换为小写 strtoupper() 转换为大写 lcfirst() 使一个字符串的第一个字符小写 ucfirst() 将字符串的首字母转换为大写 ucwords() 将字符串中每个单词的首字母转换为大写
8) 特殊字符处理
nl2br() addslashes() htmlspecialchars() htmlspecialchars_decode()
有关函数的系统函数
function_exists(): 判断一个函数是否定义过
function_get_args(): 获取传递给函数实参数列表的数组
function_get_arg($i): 获取传递给函数的第$i个实参
function_num_args(): 获取传递给函数的实参数量
时间函数
time() microtime() mktime() date() idate() strtotime() date_add() date_diff() date_default_timezone_set() date_default_timezone_get()
数学函数
max() min() round() ceil() floor() abs() sqrt() pow() rand()
数组函数
1)指针操作函数
current() key() next() prev() end() reset() each()
1 $v = current($数组); //获得数组的当前指针所在的单元的“值” 2 3 $v = key($数组); //获得数组的当前指针所在的单元的“健”(下标) 4 5 $v = next($数组); //先将数组的指针移向下一个单元,然后取得该新单元的值。 6 7 $v = prev($数组); //先将数组的指针移向前一个单元,然后取得该单元的值。 8 9 $v = end($数组); //先将数组的指针直接移向最后一个单元, 然后取得该单元的值。 10 11 $v = reset($数组); //先将数组的指针直接移向第一个单元, 然后取得该单元的值。
2)单元操作函数
array_pop() array_push() array_shift() array_slice() array_splice()
array_pop($arr) 将数组最后一个单元弹出,数组长度减1 array_push($arr,$var,..) 将1个或多个单元压入数组的末尾 array_shift($arr) 将数组开头的单元移出数组 array_unshift($arr,$var,..) 将1个或多个单元压入数组的开始 array_slice() 从数组中取出一段 (参数类型substr
相关文章:
-
-
BZOJ1491: [NOI2007]社交网络(Floyd 最短路计数)
Description 在社交网络(socialnetwork)的研究中,我们常常使用图论概念去解释一些社会现象。不妨看这样的一个问题。 在一个社交... [阅读全文] -
一. list(列表): 用 [ ] 表示,有索引下表,可进行切片 二,可以进行增删改查. 1增 append() 在末尾增加一个数据项. 例: l... [阅读全文]
-
BZOJ3668: [Noi2014]起床困难综合症(贪心 二进制)
Description 21 世纪,许多人得了一种奇怪的病:起床困难综合症,其临床表现为:起床难,起床后精神不佳。作为一名青春阳光好少年,atm 一... [阅读全文] -
总结DevC++连接MySQL的问题,本文章不包含VS连接MySQL操作。 ... [阅读全文]
-
BZOJ2005: [Noi2010]能量采集(容斥原理 莫比乌斯反演)
Description 栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光的能量。在这些植物采集能量后, 栋栋再使用一个能量汇集... [阅读全文] -
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
上一篇: iOS中Realm数据库的基本用法
下一篇: ucenter通信原理分析
发表评论