最粗暴简单的解法就是穷举法,在这里就不展示穷举法的code了,没有什么价值~下面介绍的是在编程之美这本书中,书的作者提的一个思路。通过分治的思想,以及创建一个运算集合(保留a+b,b+a这种结果一致的运算中的一个),去设计代码。我的JS实现也是参照网上其他语言的实现改的~下面就贴出JS代码。
function node(value, exp) {
this.value = value;
this.exp = exp;
}
function equalTo24(arr) {
let answers = new Set();
let S = new Map();
let A = arr;
function run() {
for (var i = 0; i < (1 << 4); i++) {
let set = new Set();
S.set(i, set);
}
for (var i = 0; i < 4; i++) {
let n = new node(A[i], A[i] + "");
let set = new Set();
set.add(n);
S.set(1 << i, set);
}
for (var i = 1; i < (1 << 4); i++) {
fork(i);
}
let mSet = S.get((1 << 4) - 1);
for (let v of mSet.values()) {
if (v.value == 24) {
answers.add(v.exp);
}
}
if (answers.size == 0) {
console.log("It's no possible");
}
else {
for (let i of answers) {
console.log(i)
}
}
}
function fork(m) {
var mSet = S.get(m);
if (mSet.size > 0)
return mSet;
else {
for (var x = 1; x < m; x++) {
if ((x & m) == x) {
let s1 = fork(x);
let s2 = fork(m - x);
for (let n1 of s1)
for (let n2 of s2) {
var str = "(" + n1.exp + "+" + n2.exp + ")";
mSet.add(new node(n1.value + n2.value, str));
str = "(" + n1.exp + "-" + n2.exp + ")";
mSet.add(new node(n1.value - n2.value, str));
str = "(" + n2.exp + "-" + n1.exp + ")";
mSet.add(new node(n2.value - n1.value, str));
str = "(" + n1.exp + "*" + n2.exp + ")";
mSet.add(new node(n1.value * n2.value, str));
if (n1.value != 0) {
str = "(" + n2.exp + "/" + n1.exp + ")";
mSet.add(new node(n2.value / n1.value, str));
}
if (n2.value != 0) {
str = "(" + n1.exp + "/" + n2.exp + ")";
mSet.add(new node(n1.value / n2.value, str));
}
}
}
}
return mSet;
}
}
run()
}
测试的Case:
var arr = [12,40,5,6];
equalTo24(arr)
(12*((40/5)-6))
(12*(6-(40/5)))
((12-(40/5))*6)
(((40/5)-12)*6)
(6*(12-(40/5)))
(6*((40/5)-12))
(((40/5)-6)*12)
((6-(40/5))*12)