一、算法介绍
根据华为机试题完善的算法,此次算法输入:4个数字,输出:所有结果为24的计算公式
华为机试题
二、思路及代码
1.思路
暴力解法,穷举所有组合产生的运算结果。
用到了组合思想
- 从长度为4的数组arr4中取出2个数,共计6种组合数C24
- 计算每组组合数的6种结果:a+b;a-b;b-a;a*b;若b!=0,a/b;若a!=0,b/a
- 将这6种计算结果分别替换原数组参与计算的两个数。
- 返回 36X3的二维数组arr3
第一层循环arr3: 选出每个长度为3的数组元素的组合数,并计算每组组合数的6种结果,将这6种计算结果分别替换原数组参与计算的两个数。每次循环返回一个18X2的二维数组arr2
第二层循环arr2: 计算数组中两个数的6种结果,将这6种计算结果分别替换原数组的两个数。每次循环返回一个6X1的二维数组arr1
第三层循环arr1: 判断数组中仅剩的1个数是否等于24,若是,将其结果push到res中
2.代码
代码如下(示例):
//计算公式的构造函数
function Equation(equa, res) {
this.equa = equa;
this.res = res;
}
//两个数计算的6种结果
function count(a, b) {
let arr = [];
arr.push(new Equation(`(${a.equa})+(${b.equa})`, a.res + b.res));
arr.push(new Equation(`(${a.equa})-(${b.equa})`, a.res - b.res));
arr.push(new Equation(`(${b.equa})-(${a.equa})`, b.res - a.res));
arr.push(new Equation(`(${a.equa})*(${b.equa})`, a.res * b.res));
if (b.res) {
arr.push(new Equation(`(${a.equa})/(${b.equa})`, a.res / b.res));
}
if (a.res) {
arr.push(new Equation(`(${b.equa})/(${a.equa})`, b.res / a.res));
}
return arr;
}
//从M个数中取2个数,计算其结果,并替换原数组参与计算的数
function takeNumCalc(arr) {
let res = []; //所有取数和计算的结果
let falg = new Array(4).fill(0); //标记数组
let path = []; //每次取数的集合
function backTracking(startIndex) {
if (path.length == 2) {
//1.得到数组中没有参与计算的数
let newarr = arr.filter((val, index) => falg[index] == 0);
//2.获取此次组合数的6种计算结果
let countres = count(...path);
//3.每次遍历返回,计算结果和数组中没有参与计算的数的新数组
countres.forEach((val) => {
res.push([...newarr, val]);
});
//4.结束此次递归
return;
}
//选数,每次从上次递归的i+1开始
for (let i = startIndex; i < arr.length; i++) {
falg[i] = 1;
path.push(arr[i]);
backTracking(i + 1);
falg[i] = 0; //回溯
path.pop();
}
}
//执行函数
backTracking(0);
//返回结果
return res;
}
let res = []; //最终结果
let arr = [5, 7, 1, 9]; //初始数组,即输入值
//将初始数组转换成Equation对象数组,便于存储计算公式
let arr4 = arr.map((val) => new Equation(val, val));
let arr3 = takeNumCalc(arr4); //得到36X3二维数组
arr3.forEach((val) => {
let arr2 = takeNumCalc(val); //得到18X2二维数组
arr2.forEach((val) => {
let arr1 = takeNumCalc(val); //得到6X1二维数组
arr1.forEach((val) => {
if (val[0].res == 24) {
res.push(val[0]);
}
});
});
});
console.log(res);