PHP方法实现1-9数列中添加‘+’,‘-’或'',使和为100,并输出数列

今天收到个题目:编写一个在1,2,3,4,5,6,7,8,9(顺序不能变)数字之间插入 + 或- 或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性。例如 1+2+34-5+67-8+9=100; 
一开始在网上找了好久,发现这个问题是在一篇很火的文章《每个程序员1小时内必须解决的5个编程问题》上的第五题 ,如图: 
这里写图片描述 
提供一个php的解决方法,如下:

$str = '123456789';
$newStr = '';
function listarr($str, $newStr)
{
    if(strlen($str) == 1){
        $newStr = $newStr.'9';//最后一位9需要手动加上;
        $v = eval("return $newStr;"); //计算公式的结果;
        if($v == 100){
            echo $newStr."<hr/>";
        }
    } else {
        $newStr .= substr($str, 0, 1);
        $str = substr($str,1);
        //递归三种可能
        listarr($str, $newStr.'+');
        listarr($str, $newStr.'-');
        listarr($str, $newStr);
    }
}
listarr($str, $newStr);

 

但是要注意,在求和的时候使用的是eval函数,这个函数是非常非常危险的,很多人都说木马就是利用eval函数,所以基本上所有的服务器都会禁用eval的; 
如果不采用eval函数的话,就需要另外写一个方法手动计算公式的值了:

 1 $str = '123456789';
 2 $newStr = '';
 3 function listarr($str, $newStr)
 4 {
 5     if(strlen($str) == 1){
 6         $newStr = $newStr.'9';//手动加上最后一个9;
 7         $res = cal($newStr);
 8         if($res){
 9             echo $newStr."<hr/>";
10         }
11     } else {
12         $newStr .= substr($str, 0, 1);
13         $str = substr($str, 1);
14 
15         //递归三种可能
16         listarr($str, $newStr.'+');
17         listarr($str, $newStr.'-');
18         listarr($str, $newStr);
19 }
20 function cal($str)
21 {
22     $arr = explode('+', $str);//分割数列,储存至数组中
23     $sum = 0;
24     foreach($arr as $v){
25         if(is_numeric($v)){   //判断分割的数组是否为纯数字;
26             $sum += $v;
27         } else {
28             $vArr = explode('-', $v); //对含减号的数组再进行一次分割;
29             $sum += $vArr[0];   //第一个值前的运算符为+;
30             unset($vArr[0]);
31             $s = array_sum($vArr);
32             $sum -= $s;
33         }
34     }
35     if($sum == 100){
36         return true;
37     } else {
38         return false;
39     }
40 }
41 listarr($str, $newStr);

 

最后补充一个通用模板

 1 /**
 2  * $data array 要计算的数列组合;
 3  * $flag array 可用的运算符号
 4  * $result int 要求的和的值
 5  */
 6 function think_exp($data, $flag, $result)
 7 {
 8     $m = count($data);//m个数字
 9     $n = count($flag);//n个符号
10     $num =  str_split( sprintf ( "%0". ($m - 1) ."d",0) ); //生成一个[0,0,0,0,...,0]的数组
11     $exp = '';
12     while($num != 'Ok' ){
13         $line = '';
14         for ( $i=0; $i<$m; $i++  )  {
15             $line .= $data[$i]; //列出所有的式子;
16             if( isset($num[$i]) ) $line .= $flag[$num[$i]];
17         }
18         if ( eval('return '.$line.';') == $result) {
19             $exp .= $line.'='.$result.'<br />';
20         }
21         $num =  getNext($num , 0, $n);
22     }
23     return $exp;
24 }
25 function getNext($next_num , $position = 0, $n){
26     if ($position == count($next_num)) return 'Ok';
27     $next_num[$position] = $next_num[$position] + 1;
28     if ($next_num[$position] < $n) {
29         return $next_num;
30     } else {
31         $next_num[$position] = 0;
32         return getNext($next_num, $position + 1, $n);
33     }
34 }

 

 //计算题目 echo "<font color=red>think_exp(array(1,2,3,4,5,6,7,8,9), array('','+','-','*','/'), 100); </font><br />"; echo think_exp(array(1,2,3,4,5,6,7,8,9), array('','+','-'), 100);
转自Kit_G的博客

转载于:https://www.cnblogs.com/rcwg/p/8609170.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值