PHP中的一些小算法

来源:互联网 发布:sql 选取时间段 编辑:程序博客网 时间:2024/06/14 15:28

1.数组反转函数

/** *  数组反转函数 *  @param array arr   *  @return array */function reverse($arr){    $count = count($arr);    $left = 0;    $right = $count - 1;    // 第一个和最后一个互换,第二个和倒数第二个互换,依次反转    while ($left < $right)    {        $temp = $arr[$left];        $arr[$left++] = $arr[$right];        $arr[$right--] = $temp;    }    return $arr;}

2.找出两个有序数字元素数组中的相同元素

/** *  找出两个有序数字元素数组中的相同元素 *  @param array $arr1 *  @param array $arr2 *  @return array */function find_common($arr1, $arr2){    $i = $j = 0;    $common = array();    $count1 = count($arr1);    $count2 = count($arr2);    // 因为是有序数组,从arr1和arr2的第一个元素开始相比,比完没有则执行一遍,有相等的从相等的后一个开始继续比    while ($i < $count1 && $j < $count2)    {        if ($arr1[$i] < $arr2[$j]) {            $i++;        } elseif ($arr1[$i] > $arr2[$j]) {            $j++;        } else {            $common[] = $arr1[$i];            $i++;            $j++;        }    }    // 移除数组中重复的值    return array_unique($common);}

3.将数组中的元素随机打乱

 /**  *  将数组中的元素打乱  *  @param array $arr  *  @return array  */function custom_shuffle($arr){    $count = count($arr);    // 从数组中随机获取一个和当前元素交换,最多交换的次数等于该数组的元素个数    for ($i = 0; $i < $count; $i++)    {        $rand_pos = mt_rand(0,$count);        if ($rand_pos != $i) {            $temp = $arr[$i];            $arr[$i] = $arr[$rand_pos];            $arr[$rand_pos] = $temp;        }    }    return $arr;  }

4.一个数字字母相连的字符串,让数字和字母对应

 /**  * 将一个数字字母相连的字符串,使数字和字母对应  * @param $str  */ function nember_alphabet($str) {     // 通过正则表达式将字符串分割成数组,-1、0、null表示不限制个数,否则显示设置的个数,最后一个将返回剩余的子串     $number = preg_split('/[a-z]+/', $str, -1, PREG_SPLIT_NO_EMPTY);     $alphabet = preg_split('/d+/', $str, -1, PREG_SPLIT_NO_EMPTY);     $count = count($number);     for ($i = 0; $i < $count; $i++)     {         echo $number[$i].':'.$alphabet[$i].'<br>';     } } $str = '1a3bb44a2ac'; number_alphabet($str); // 1:a 3:bb 44:a 2:ac

5.求n以内的质数

 /**  * 求n以内的质数  * 想到高中时老默写不出来,后来死记硬背,哈哈,唉,岁月如歌  * @param int $n  * @return array  */function get_prime($n){    // n以内的质数数组    $prime = array(2);    // 所有的偶数都不是质数,所以去掉    for ($i = 3; $i < $n; $i += 2)    {        // 先将n开平方根        $sqrt = intval(sqrt($i));        // 计算3到平方根之间的数能否被整除        for ($j = 3; $j <= $sqrt; $j += 2)        {            if ($i % $j == 0) {                break;            }        }        // 如果是质数,加入数组        if ($j > $sqrt) {            array_push($prime, $i);        }    }    return $prime;}

6.约瑟夫环问题

/** *  获取最后那个数 *  算法的魅力就是打开你的新世界,这个算法就有点精髓 *  @param int $n *  @param int $m *  @return int */function get_king_mokey($n, $m){    // 生成从1到$n的自然数数组    $arr = range(1, $n);    $i = 0;    while (count($arr) > 1)    {        $i++;        // 删除第一个元素,并返回被删除的值        $survice = array_shift($arr);        // 如果这个值不是第$m值,再将值插入到数组后面        if ($i % $m != 0) {            array_push($arr, $survice);        }    }    return $arr[0];}

7.寻找一个数组里最小的k个数

/** * 从n个整数中获取最小的k个数 * @param  array $arr * @param  int $k * @return array */function get_min_array($arr, $k){    $n = count($arr);    $min_array = array();    for ($i = 0; $i < $n; $i++) {        // 默认前k个为最小        if ($i < $k) {            $min_array[$i] = $arr[$i];        } else {            if ($i == $k) {                // 取出最大值的位置                $max_pos = get_max_pos($min_array);                // 获取$min_array数组中最大的数                $max = $min_array[$max_pos];            }            // 如果比最大的小,则替换掉$min_array数组中最大的值            if ($arr[$i] < $max) {                $min_array[$max_pos] = $arr[$i];                // 重新获取$min_array数组中最大的值跟$arr数组中的剩下的数继续比对                $max_pos = get_max_pos($min_array);                $max = $min_array[$max_pos];            }        }    }    return $min_array;}/** * 获取最大的位置 * @param  array $arr * @return array */function get_max_pos($arr){    $pos = 0;    for ($i = 1; $i < count($arr); $i++) {        if ($arr[$i] > $arr[$pos]) {            $pos = $i;        }    }    return $pos;}$array = [1, 100, 20, 22, 33, 44, 55, 66, 23, 79, 18, 20, 11, 9, 129, 399, 145, 2469, 58];$min_array = get_min_array($array, 10);print_r($min_array);

8.二分查找

/** * 二分查找 * @param  array $array 数组 * @param  int $n 数组数量 * @param  int $value 要寻找的值 * @return int */function binary_search($array, $n, $value){    $left = 0;    $right = $n - 1;    while ($left <= $right) {        // 找到中间位置的下标        $mid = intval(($left + $right) / 2);        if ($value > $mid) {            $right = $mid + 1;        } elseif ($value < $mid) {            $left = $mid - 1;        } else {            return $mid;        }    }    return -1;}

9.给定一个有序整数序列,找出绝对值最小的元素

/** * 获取绝对值最小的元素 * @param  array $arr * @return int   */function get_min_abs_value($arr){    //如果符号相同,直接返回    if (is_same_sign($arr[0], $arr[$n - 1])) {        return $arr[0] >= 0 ? $arr[0] : $arr[$n - 1];    }    //二分查找    $n = count($arr);    $left = 0;    $right = $n - 1;    while ($left <= $right) {        if ($left + 1 === $right) {            return abs($arr[$left]) < abs($arr[$right]) ? $arr[$left] : $arr[$right];        }        $mid = intval(($left + $right) / 2);        if ($arr[$mid] < 0) {            $left = $mid + 1;        } else {            $right = $mid - 1;        }    }}/** * 判断符号是否相同 * @param  int  $a * @param  int  $b * @return boolean   */function is_same_sign($a, $b){    if ($a * $b > 0) {        return true;    } else {        return false;    }}

10.找出有序数组中随机3个数和为0的所有情况

/** *  @param $arr */function three_sum($arr){    $n = count($arr);    $return = array();    for ($i=0; $i < $n; $i++) {        $left = $i + 1;        $right = $n - 1;        while ($left <= $right) {            $sum = $arr[$i] + $arr[$left] + $arr[$right];            if ($sum < 0) {                $left++;            } elseif ($sum > 0) {                $right--;            } else {                $numbers = $arr[$i] . ',' . $arr[$left] . ',' . $arr[$right];                if (!in_array($numbers, $return)) {                    $return[] = $numbers;                }                $left++;                $right--;            }        }    }    return $return;}$arr = [-10, -9, -8, -4, -2, 0, 1, 2, 3, 4, 5, 6, 9];var_dump(three_sum($arr));

11.编写一个PHP函数,求任意n个正负整数里面最大的连续和,要求算法时间复杂度尽可能低。

/** * 获取最大的连续和 * @param  array $arr * @return int */function max_sum_array($arr){    $currSum = 0;    $maxSum = 0; // 数组元素全为负的情况,返回最大数    $n = count($arr);    for ($i = 0; $i < $n; $i++) {        if ($currSum >= 0) {            $currSum += $arr[$i];        } else {            $currSum = $arr[$i];        }    }    if ($currSum > $maxSum) {        $maxSum = $currSum;    }    return $maxSum;}

原文链接:http://coffeephp.com/articles/4

原创粉丝点击