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;
}