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

来源:互联网 发布:申报数据库免费吗 编辑:程序博客网 时间:2024/05/16 15:44

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

$str = '123456789';$newStr = '';function listarr($str, $newStr){    if(strlen($str) == 1){        $newStr = $newStr.'9';//手动加上最后一个9;        $res = cal($newStr);        if($res){            echo $newStr."<hr/>";        }    } else {        $newStr .= substr($str, 0, 1);        $str = substr($str, 1);        //递归三种可能        listarr($str, $newStr.'+');        listarr($str, $newStr.'-');        listarr($str, $newStr);}function cal($str){    $arr = explode('+', $str);//分割数列,储存至数组中    $sum = 0;    foreach($arr as $v){        if(is_numeric($v)){   //判断分割的数组是否为纯数字;            $sum += $v;        } else {            $vArr = explode('-', $v); //对含减号的数组再进行一次分割;            $sum += $vArr[0];   //第一个值前的运算符为+;            unset($vArr[0]);            $s = array_sum($vArr);            $sum -= $s;        }    }    if($sum == 100){        return true;    } else {        return false;    }}listarr($str, $newStr);

再补充一个方法:

function index(){    $bol = ['', '-', '+'];    $num = [0, 0, 0, 0, 0, 0, 0, 0];//8个运算符的位置;    do{        $var = "1{$bol[$num[0]]}2{$bol[$num[1]]}3{$bol[$num[2]]}4{$bol[$num[3]]}5{$bol[$num[4]]}6{$bol[$num[5]]}7{$bol[$num[6]]}8{$bol[$num[7]]}9";        $v = eval("return $var;");        if($v == 100) echo $var.'<hr/>';        $num = getNextNum($num);    } while($num != 'ok');}function getNextNum($num, $position=0){    if($position == 8) return 'ok';    $num[$position] = $num[$position] + 1;    if($num[$position] < 3){        return $num;    } else {        $num[$position] = 0;        return getNextNum($num, $position+1);    }}index();

最后补充一个通用模板

/** * $data array 要计算的数列组合; * $flag array 可用的运算符号 * $result int 要求的和的值 */function think_exp($data, $flag, $result){    $m = count($data);//m个数字    $n = count($flag);//n个符号    $num =  str_split( sprintf ( "%0". ($m - 1) ."d",0) ); //生成一个[0,0,0,0,...,0]的数组    $exp = '';    while($num != 'Ok' ){        $line = '';        for ( $i=0; $i<$m; $i++  )  {            $line .= $data[$i]; //列出所有的式子;            if( isset($num[$i]) ) $line .= $flag[$num[$i]];        }        if ( eval('return '.$line.';') == $result) {            $exp .= $line.'='.$result.'<br />';        }        $num =  getNext($num , 0, $n);    }    return $exp;}function getNext($next_num , $position = 0, $n){    if ($position == count($next_num)) return 'Ok';    $next_num[$position] = $next_num[$position] + 1;    if ($next_num[$position] < $n) {        return $next_num;    } else {        $next_num[$position] = 0;        return getNext($next_num, $position + 1, $n);    }}//计算题目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);
阅读全文
1 0
原创粉丝点击