今天朋友问到一个题目:从1到10的十个数字中,取4个不重复数字,取数顺序不限,只通过加、减、乘三种运算,运算使用次数不限,各类不限,不允许使用括号,实现计算结果为24的数。问有多少种方案。
如:取4个字数分别为10,2,4,8;则有2种输出方案:10+2+4+8和10*2-4+8两种输出方案。
实现思路:
1、取4个不重复的数字;
2、通过不同的组合方式,生成数学表达式;
3、执行表达式返回结果,如为24则是我们需要的。
问题:数学表达式我生成了字符串形式,而字符串无法直接返回运算结果。本来通过eval函数返回的,由于考虑到安全问题,服务器会禁用此函数,实现不具通用性和可移值性。通过查询资料发现可以通过逆波兰式来处理(https://my.oschina.net/u/566545/blog/103030 ),帮引用了此类来实现运算。
代码:
<?php
include_once('calc.php');//此类参考 https://my.oschina.net/u/566545/blog/103030
class p24Point{
public function __contruct()
{
}
/**
* 从1到10中任意拿4个数字,不能重复取,顺序不限,只使用加、减、乘三种运算(不能使用括号),运算使用次数不限。
* 问:共有几种运算方案
*/
public function puker24Point()
{
for($i = 1; $i <= 10; $i++){
for($j = 1; $j <= 10; $j++){
if($i == $j){
continue;
}
for($k = 1; $k <= 10; $k++){
if($i == $k || $j == $k){
continue;
}
for($l = 1; $l <= 10; $l++){
if($i == $l || $j == $l || $k == $l){
continue;
}
//所有组合情况
$this->to24Point($i, $j, $k, $l);
}
}
}
}
}
/**
*
* 通过4个数字生成表达式
*/
private function to24Point($a, $b, $c, $d)
{
$ysf = array('+', '-', '*');
foreach ($ysf as $ys){
foreach($ysf as $ys2){
foreach($ysf as $ys3){
$str = $a .$ys. $b .$ys2. $c .$ys3. $d;
$calc = new \Calc($str);
$result = $calc->calculate();
if($result == 24){
echo $str.'=24;'.'<br/>';
}
/*$val = eval('return '.$str.';');
if($val == 24){
echo $str.'=24;'.'<br/>';
}*/
}
}
}
return true;
}
}
$test = new p24Point();
$test->puker24Point();
结果:共有1332条运算符合条件。