PHP实现八大算法

计算数组乘积,array_product()

  1. 直接插入排序(Straight Insertion Sort)
  2. 希尔排序(Shells Sort)
  3. 直接选择排序(Straight Selection Sort)
  4. 堆排序(Heap Sort)
  5. 冒泡排序(Bubble Sort)
  6. 快速排序(Quick Sort)
  7. 归并排序(Merge Sort)
  8. 桶排序(Bucket Sort)/基数排序(Radix Sort)
  9. 各种排序算法性能比较

排序有内部排序和外部排序之分,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。我们这里说的八大排序算法均为内部排序。
1.直接插入算法

// 第一种
function insert_sort($arr){
    for ($i = 0; $i < count($arr)-1; $i++){
        for($j = $i+1; $j > 0; $j--){
            if($arr[$j] > $arr[$j-1]){
                $temp = $arr[$j];
                $arr[$j] = $arr[$j-1];
                $arr[$j-1] = $temp;
            }
        }
    }
    return $arr;
}

$insert_sort = insert_sort([19, 22, 20, 12, 13, 15, 25, 26]);
var_dump($insert_sort);

// 第二种
function insert_sort($arr){
    for ($i = 0; $i < count($arr)-1; $i++){
        $j = $i + 1;
        while($j > 0){
            if($arr[$j] > $arr[$j-1]){
                $temp = $arr[$j];
                $arr[$j] = $arr[$j-1];
                $arr[$j-1] = $temp;
            }
            $j--;
        }
    }
    return $arr;
}

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

2.希尔排序
3.直接选择排序

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;
            }
        }
        if ($p != $i){
            $tmp = $arr[$p];
            $arr[$p] = $arr[$i];
            $arr[$i] = $tmp;
        }
    }
    return $arr;
}

4.堆排序
5.冒泡排序法的基本思想是:对待排序记录关键字从后往前(逆序)进行多遍扫描,当发现相邻两个关键字的次序与排序要求的规则不符时,就将这两个记录进行交换。这样,关键字较小的记录将逐渐从后面向前面移动,就象气泡在水中向上浮一样,所以该算法也称为气泡排序法。

// 冒泡排序
function bubbleSort($arr)
{
    $len = count($arr);
    // 该层循环控制 需要冒泡的轮数
    for ($i=1; $i<$len; $i++) {
        // 该层循环用来控制每轮 冒出一个数 需要比较的次数
        for ($j=0; $j<$len-$i; $j++) {
            if($arr[$j] > $arr[$j+1]) {
                $tmp = $arr[$j+1]; // 声明一个临时变量
                $arr[$j+1] = $arr[$j];
                $arr[$j] = $tmp;
            }
        }
    }
    return $arr;
}

6.快速排序算法

function quickSort($arr)
{
    if (!is_array($arr)) return false;
    $len = count($arr);
    if ($len <= 1) return $arr;
    $a = $b = array();
    for ($i = 1; $i < $len; $i++){
        if ($arr[$i] < $arr[0]){
            $a[] = $arr[$i];
        }else{
            $b[] = $arr[$i];
        }
    }
    $a = quickSort($a);
    $b = quickSort($b);
    return array_merge($a, array($arr[0]), $b);
}

7.归并排序算法【注意:数组按值传输】

function merge_sort(&$A, $p, $r)
{
    if($p < $r){
        $q = floor(($p + $r)/2);
        merge_sort($A, $p, $q);
        merge_sort($A, $q+1, $r);
        merge($A, $p, $q, $r);
    }
}
function merge(&$A, $p, $q, $r)
{
    // 哨兵牌法
    $n1 = $q - $p + 1;
    $n2 = $r - $q;
    for($i = 0; $i < $n1; $i++){
        $L[$i] = $A[$p+$i];
    }
    for($j = 0; $j < $n2; $j++){
        $R[$j] = $A[$q+$j+1];
    }
    // 防止越界(哨兵)
    $L[$n1] = $R[$n2] = PHP_INT_MAX;
    $i = $j = 0;
    for($k = $p; $k <= $r; $k++){
        if($L[$i] <= $R[$j]){
            $A[$k] = $L[$i];
            $i++;
        }else{
            $A[$k] = $R[$j];
            $j++;
        }
    }
}

8.基数排序算法

PHP交叉排列的组合算法

应用场景商城类多规格组合如:
['红色','白色','蓝色','黑色']
['S','M','L','XL','XXL']

需要得到能有多少种组合

$combine_array = [['红色','白色','蓝色','黑色'],['S','M','L','XL','XXL']]
// 交叉排列的组合算法
protected function combine($array)
{
    $heads = $array[0];
    for ($i = 1; $i < count($array); $i++){
        if (count($array[$i])){
            $heads = $this->addNewType($heads, $array[$i]);
        }
    }
    return $heads;
}

protected function addNewType($heads, $choices)
{
    $result = [];
    for ($i = 0; $i < count($heads); $i++){
        for ($j = 0; $j < count($choices); $j++){
            $result[] = $heads[$i] . ':' . $choices[$j];
        }
    }
    return $result;
}

php导出数据保存到cvs文存储到目录

设置内存限制

set_time_limit(0);
ini_set('memory_limit', '1024M');

// 设置cvs第一行数据
$header = ['A1','B1','C1','D1'];
$csvList = [
    ['A2','B2','C2','D2'],
    ['A3','B3','C3','D3'],
    ['A4','B4','C4','D4'],
];
//下载csv的文件名
$filename = getcwd() . '/csv/用户骑行数据' . date('YmdHis', $time_range) . '.csv';
exportCsv($data, $title_arr, $file_name = '')
{
    $csv_data = '';
    // 标题
    $num = count($title_arr);
    for ($i = 0; $i < $num - 1; ++$i) {
        $csv_data .= '"' . $title_arr[$i] . '",';
    }
    if ($num > 0) {
        $csv_data .= '"' . $title_arr[$num - 1] . "\"\r\n";
    }
    foreach ($data as $k => $row) {
        for ($i = 0; $i < $num - 1; ++$i) {
            $row[$i] = str_replace("\"", "\"\"", $row[$i]);
            $csv_data .= '"' . $row[$i] . '",';
        }
        $csv_data .= '"' . $row[$num - 1] . "\"\r\n";
        unset($data[$k]);
    }
    $file_name = empty($file_name) ? date('Y-m-d-H-i-s', time()) : $file_name;
    file_put_contents($file_name, $csv_data) ;
}
exportCsv($csvList, $header, $filename);

php获取多边形GPS中心点坐标getGpsCenter

直接帖方法
    $gps_data = [
        [119.182468,34.603796],
        [119.182635,34.603347],
        [119.182743,34.603370],
        [119.182575,34.603846].
    ];
    // 获取GPS中心点坐标
    function getGpsCenter($gps_data = [])
    {
        if (!is_array($gps_data)) return false;
        $num_coords = count($gps_data);

        $X = 0.0;
        $Y = 0.0;
        $Z = 0.0;

        foreach ($gps_data as $val)
        {
            #$lon = $coord[1] * pi() / 180;
            $lng = deg2rad($val[0]);
            #$lat = $coord[0] * pi() / 180;
            $lat = deg2rad($val[1]);

            $a = cos($lat) * cos($lng);
            $b = cos($lat) * sin($lng);
            $c = sin($lat);

            $X += $a;
            $Y += $b;
            $Z += $c;
        }

        $X /= $num_coords;
        $Y /= $num_coords;
        $Z /= $num_coords;

        $lng = atan2($Y, $X);
        $hyp = sqrt($X * $X + $Y * $Y);
        $lat = atan2($Z, $hyp);

        #return array($lat * 180 / pi(), $lon * 180 / pi());
        return array(rad2deg($lng), rad2deg($lat));
    }