PHP常用算法

一、冒泡排序

基本思想:

对需要排序的数组从后往前(逆序)进行多遍的扫描,当发现相邻的两个数值的次序与排序要求的规则不一致时,就将这两个数值进行交换。这样比较小(大)的数值就将逐渐从后面向前面移动。

//代码利用了双循环来实现排序。 外循环用来控制所有轮次,内循环用来控制每一轮的排序
for ($i = 0; $i < count($sortArr) - 1; $i++) {
  $isChange = false;
    for ($j = $i + 1; $j < count($sortArr); $j++) {
        if ($sortArr[$i] > $sortArr[$j]) {
            $temp = $sortArr[$i];
            $sortArr[$i] = $sortArr[$j];
            $sortArr[$j] = $temp;
       $isChange = true; 
        }
    }
  //假如所有数列都是有序的,那么第一轮第一次排序之后所有数列没有发生一次交换,这时候其实已经可以不用再继续后面的循环了
  if(!isChange){
    break;
  }
} 

二、快速排序

基本思想:

在数组中挑出一个元素(多为第一个)作为标尺,扫描一遍数组将比标尺小的元素排在标尺之前,将所有比标尺大的元素排在标尺之后,通过递归将各子序列分别划分为更小的序列直到所有的序列顺序一致。

//快速排序
function quickSort($arr)
{
    $len = count($arr);
    if ($len <= 1) {
        return $arr;
    }

    $v = $arr[0];
    $low = $up = array();
    for ($i = 1; $i < $len; ++$i) {
        if ($arr[$i] > $v) {
            $up[] = $arr[$i];
        } else {
            $low[] = $arr[$i];
        }
    }
    $low = quickSort($low);
    $up = quickSort($up);

    return array_merge($low, array($v), $up);
}

//快速排序第二种方法
for ($i = 0; $i < count($sortArr) - 1; $i++) {
    for ($j = count($sortArr) - 1; $j > $i; $j--) {
        if ($sortArr[$i] > $sortArr[$j]) {
            $temp        = $sortArr[$i];
            $sortArr[$i] = $sortArr[$j];
            $sortArr[$j] = $temp;
        }
    }
}

 

三、二分查找

基本思想:

假设数据是按升序排序的,对于给定值x,从序列的中间位置开始比较,如果当前位置值等于x,则查找成功;若x小于当前位置值,则在数列的前半段中查找;若x大于当前位置值则在数列的后半段中继续查找,直到找到为止。(数据量大的时候使用)

// 使用PHP描述顺序查找和二分查找(也叫做折半查找)算法,顺序查找必须考虑效率,对象可以是一个有序数组
/**
* 二分查找法(数组中查找某个元素)
* @param array $arr 要查找的数组
* @param int $low 查找的起始位置
* @param array $high 查找的结束位置
* @param mixed $k 要查找的目标值
* @return int 存在此值返回key,不存在返回-1
*/

  function bin_search($arr,$low,$high,$k)
  {
    if($low <= $high)
    {
      $mid = intval(($low + $high)/2);
      if($arr[$mid] == $k)
      {
        return $mid;
      }
      else if($k < $arr[$mid])
      {
        return bin_search($arr,$low,$mid-1,$k);
      }
      else
      {
        return bin_search($arr,$mid+1,$high,$k);
      }
    }
    return -1;
  }

  $arr = array(1,2,3,4,5,6,7,8,9,10);

  print(bin_search($arr,0,9,3)); 

四、顺序查找

基本思想:

从数组的第一个元素开始一个一个向下查找,如果有和目标一致的元素,查找成功;如果到最后一个元素仍没有目标元素,则查找失败。

/**
 * 顺序查找(数组里查找某个元素)
 * @param array $array 要查找的数组
 * @param array $n 查找的结束位置 + 1
 * @param mixed $target 要查找的目标值
 */
function seq_sch($array, $n, $target)
{
    for ($i = 0; $i < $n; $i++) {
        if ($array[$i] == $target) {
            break;
        }
    }
    if ($i < $n) {
        return $i;
    } else {
        return -1;
    }
}

$array = [77, 79, 89];
$find = seq_sch($array, count($array), 89);
var_dump($find);

选择排序

基本思想:在要排序的一组数中,选出最小的一个数与第一个位置的数交换。然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。

代码实现:

function selectSort($arr) {
//双重循环完成,外层控制轮数,内层控制比较次数
 $len=count($arr);
    for($i=0; $i<$len-1; $i++) {
        //先假设最小的值的位置
        $p = $i;
        
        for($j=$i+1; $j<$len; $j++) {
            //$arr[$p] 是当前已知的最小值
            if($arr[$p] > $arr[$j]) {
            //比较,发现更小的,记录下最小值的位置;并且在下次比较时采用已知的最小值进行比较。
                $p = $j;
            }
        }
        //已经确定了当前的最小值的位置,保存到$p中。如果发现最小值的位置与当前假设的位置$i不同,则位置互换即可。
        if($p != $i) {
            $tmp = $arr[$p];
            $arr[$p] = $arr[$i];
            $arr[$i] = $tmp;
        }
    }
    //返回最终结果
    return $arr;
} 

插入排序

基本思想:在要排序的一组数中,假设前面的数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。

代码实现:

function insertSort($arr) {
    $len=count($arr); 
    for($i=1, $i<$len; $i++) {
        $tmp = $arr[$i];
        //内层循环控制,比较并插入
        for($j=$i-1;$j>=0;$j--) {
            if($tmp < $arr[$j]) {
                //发现插入的元素要小,交换位置,将后边的元素与前面的元素互换
                $arr[$j+1] = $arr[$j];
                $arr[$j] = $tmp;
            } else {
                //如果碰到不需要移动的元素,由于是已经排序好是数组,则前面的就不需要再次比较了。
                break;
            }
        }
    }
    return $arr;
}

 

七、写一个函数,能够遍历一个文件下的所有文件和子文件夹

 function my_scandir($dir)
  {
    $files = array();
    if($handle = opendir($dir))
    {
      while (($file = readdir($handle))!== false) 
      {
        if($file != '..' && $file != '.')
        {
          if(is_dir($dir."/".$file))
          {
            $files[$file]=my_scandir($dir."/".$file);
          }
          else
          {
            $files[] = $file;
          }
        }
      }

      closedir($handle);
      return $files;
    }
  }

  var_dump(my_scandir('../')); 

八、写一个函数,尽可能高效的从一个标准url中取出文件的扩展名

function getExt($url)
  {
    $arr = parse_url($url);//parse_url解析一个 URL 并返回一个关联数组,包含在 URL 中出现的各种组成部分
    //'scheme' => string 'http' (length=4)
    //'host' => string 'www.sina.com.cn' (length=15)
    //'path' => string '/abc/de/fg.php' (length=14)
    //'query' => string 'id=1' (length=4)
    $file = basename($arr['path']);// basename函数返回路径中的文件名部分
    $ext = explode('.', $file);
    return $ext[count($ext)-1];
  }

  print(getExt('http://www.sina.com.cn/abc/de/fg.html.php?id=1'));

 

九、实现中文字符串截取无乱码的方法

可使用mb_substr,但是需要确保在php.ini中加载了php_mbstring.dll,即确保“extension=php_mbstring.dll”这一行存在并且没有被注释掉,否则会出现未定义函 数的问题。

posted @ 2020-03-11 18:01  xiaobingch  阅读(1169)  评论(0编辑  收藏  举报