PHP给定值通过四则运算,求运算表达式

PHP给定值通过四则运算,求运算表达式

https://blog.csdn.net/luochuan/article/details/7258907

针对原有算法进行了优化如下:
1、原文只显示一个表达式,现在显示所有;
2、显示所有会出现重复,增加重复过滤;
3、原文计算了绝对值,现在去除负数结果;
4、增加了表达式总数显示;

https://blog.csdn.net/zhangyunwei_Blog/article/details/105335446
同样是求解运算表达式,
这个python的写法有一定的局限性。

<?php

/**
 * 将给定的四个数做四则运算,每个数只能用一次,结果得到给定的值,求该运算表达式
 * $n:数组四个数可以是任意0-99
 * $r:要运算的结果值
 */

$n = [1,2,3,4];
$r = 30;
$total = $m = 0;
$l = count($n);
$bloom = [];

get41($n,$l);

echo "一共有 $total 种计算方式";

/**
 * 执行四则运算的主方法-递归方法
 * @param $n 要操作的数的数组,数可以为表达式
 * @param $l 该数组的有意义的元素的个数
 */
function get41($n,$l)

{
    global $r,$total,$bloom;

    if ($l == 1) {
        /**
         * 构造php语句,并eval执行表达式,如果返回给定值,则打印表达式并退出
         */
        $result = 'return ' . $n[0] . ';';
        if (eval($result) == $r) {
            if(!in_array($n[0],$bloom)){
                $total ++;
                echo $n[0]."=".$r.'<br>';
                $bloom[] = $n[0];
            }
        }
    }

    for ($i= 0; $i< $l; $i++) {
        for ($j= $i+1; $j< $l; $j++) {
            /**
             * 获取当前要进行四则运算的两个数
             * $n[$i]和它的下一个数$n[$j]
             */
            $nl = $n[$i];
            $nr = $n[$j];
            /**
             * 将当前数与其下一个数的四则运算表达式push入$n数组的第$i个元素内
             * 将$n数组的最后一个元素push入$n数组的第$i+1($j)个元素内
             * 并将$l的值-1(由于最后一个元素已经push入前面的元素中,所以有意义的元素个数要-1)
             * 然后递归调用get41
             */
            $n[$i] = '('.$nl.'+'.$nr.')';
            $n[$j] = $n[$l-1];
            get41($n,$l-1);

            $n[$i] = '('.$nl.'-'.$nr.')';
            $n[$j] = $n[$l-1];
            get41($n,$l-1);

            $n[$i] = '('.$nr.'-'.$nl.')';
            $n[$j] = $n[$l-1];
            get41($n,$l-1);

            $n[$i] = '('.$nl.'*'.$nr.')';
            $n[$j] = $n[$l-1];
            get41($n,$l-1);

            if ($nr != 0) {
                $n[$i] = '('.$nl.'/'.$nr.')';
                $n[$j] = $n[$l-1];
                get41($n,$l-1);
            }

            if ($nl != 0) {
                $n[$i] = '('.$nr.'/'.$nl.')';
                $n[$j] = $n[$l-1];
                get41($n,$l-1);
            }

            /**
             * 如果下一层递归返回false,代表未找到表达式
             * 则还原$n数组,$n[$i] = $nl; $n[$j] = $nr;
             * 并进入下一次的for+$j循环体
             */
            $n[$i] = $nl;
            $n[$j] = $nr;
        }
    }
    return false;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值