美文网首页
PHP彩票复式排列组合算法

PHP彩票复式排列组合算法

作者: 全栈码农 | 来源:发表于2021-02-23 14:15 被阅读0次

    如下需求
    需要将用户选择的01,02,03,04这4个号码按照两个数为一组的组合下注,并且按照顺序,每个组合不会因为大小顺序,重复出现多次
    通过手工计算我们可以得到
    ["01", "02"],["01", "03"],["01", "04"],["02", "03"],["02", "04"],["03", "04"]
    共计6个组合

    像这种计算我们可以使用简单的for循环来实现组合

    $checkedData = ["01","02","03","04"];
    $boxData = [];
    for ($i = 0; $i < count($checkedData); $i++) {
        $tempData = [$checkedData[$i]];
        foreach ($checkedData as $v) {
            if ($checkedData[$i] == $v) continue;
            $boxData[] = array_merge($tempData, [$v]);
        }
    }
    #输出结果
    [
            ["01","02"],
            ["01","03"],
            ["01","04"],
            ["02","01"],
            ["02","03"],
            ["02","04"],
            ["03","01"],
            ["03","02"],
            ["03","04"],
            ["04","01"],
            ["04","02"],
            ["04","03"]
        ]
    

    实际使用两个for循环会输出12种组合,这不是我们所需要的,因为每个数都出现了先后顺序重复

    改良后的代码

    $checkedData = ["01","02","03","04"];
    $boxData = [];
    for ($i = 0; $i < count($checkedData); $i++) {
        $tempData = [$checkedData[$i]];
        #每循环一次,就减去一个数组
        $bData = array_slice($checkedData, $i + 1);
        foreach ($bData as $v) {
            $boxData[] = array_merge($tempData, [$v]);
        }
    }
    
    #输出结果
    [
        ["01","02"],
        ["01","03"],
        ["01","04"],
        ["02","03"],
        ["02","04"],
        ["03","04"]
    ]
    

    嗯,没毛病,这就是我们想要的结果,想法是美好的,但现实却是扯淡的。
    现在两个数为一组这个算法是写好了,但是呢,人类的脑袋壳子不知道是怎么搞得,总有各种想法和需求,强大到你无法想象
    如什么连、什么串、什么全中不中的。。。

    然后就出现了,需要3个、4个、5个、6个。。。n个数为一组的排列组合,这可怎么搞?按照上面的代码,两个数为一组需要嵌套两个循环,N个就要N个循环,那代码得写成啥样?

    $checkedData = ["01","02","03","04"];
    $boxData = [];
    for ($i = 0; $i < count($checkedData); $i++) {
        $tempData = [$checkedData[$i]];
        #每循环一次,就减去一个数组
        $bData = array_slice($checkedData, $i + 1);
        foreach ($bData as $bk => $v) {
            $cData = array_slice($bData, $bk + 1);
            foreach ($cData ) {
               foreach ($dData ) {
                   ...
               }
            }
        }
    }
    

    没错,如果按照组合个数不断增加这样的需要,就是多少个组合就要多少个循环,这些写肯定是不行的,这里我们就需要介绍下语言的递归操作了,就是调用方法本身,让其自成一个无限循环,直到处理结果返回

    改良后的代码

    function combination($data, $len){
            $boxData = [];
            $n = count($data);
            if ($len <= 0 || $len > $n) {
                return $boxData;
            }
    
            for ($i = 0; $i < $n; $i++) {
                $tempData = [$data[$i]];
                if ($len == 1) {
                    $boxData[] = $tempData;
                } else {
                    $b = array_slice($data, $i + 1);
                    $c = combination($b, $len - 1);
                    foreach ($c as $v) {
                        $boxData[] = array_merge($tempData, $v);
                    }
                }
            }
            return $boxData;
    }
    
    $checkedData = ["01","02","03","04","05","06","07","08"];
    $data = combination($checkedData,2);//两组
    $data = combination($checkedData,3);//三组
    以此类推......
    

    还有一种需求

    需要将[0,1,2],[2,3,4],[5,6,7],[7,8,9],[1,2,3,4,5]这样复杂的数组,拆分成3个、4个、5个数为每一组的不重复数据,像什么星啦、什么同不同号啦、什么胆啦,需要用到。
    嗯,废话不多说了,主要是我感觉你应该懂了,直接上代码

    #len为需要多少个数组合
    function GetCombinationData($lists,$len = 5){
    
        //二维数组列表必须等于设定的len,否则不能组合
        if (count($lists) < $len) return false;
    
        $resLists = [];
        foreach ($lists as $k => $v) {
            $resLists = SetCombinationData($v);
        }
    
        return $resLists;
    }
    
    function SetCombinationData($val){
    
        //静态变量,保存上一个的值
        static $resLists = [];
    
        if (empty($resLists)) {
            $resLists = $val;
        }else{
            // 临时数组保存结合的结果
            $tempLists = [];
    
            //循环
            foreach ($resLists as $k => $v) {
                foreach ($val as $key => $value) {
                    $tempLists[$k . '_' . $key] = $v . ',' . $value;
                }
            }
            $resLists = $tempLists;
        }
        return $resLists;
    }
    
    $checkedData = [[0,1,2],[2,3,4],[5,6,7],[7,8,9],[1,2,3,4,5]];
    $result = GetCombinationData($checkedData,5);
    var_dump($result);
    

    相关文章

      网友评论

          本文标题:PHP彩票复式排列组合算法

          本文链接:https://www.haomeiwen.com/subject/oztlfltx.html