//分享一段计算24点的程序,用后缀表达式计算,自己写的,全排列算法来自网络,没有转化成利于阅读的中缀表达式
//可以继续优化,并转换成中缀表达式,去掉重复的(例如先后顺序的差异)
import java.util.Stack;
winion 2020-5-10
public class Main {
static char[] ops = new char[] { '?', '?', '+', '-', '*', '/' };
static int count = 0;
//数字的全排列
public static void permutation(char[] ss, int i) {
if (ss == null || i < 0 || i > ss.length) {// 1
return;
}
if (i == ss.length - 1) {// 2
gen(ss);
} else {
for (int j = i; j < ss.length; j++) {// 3
char temp = ss[j];// 交换前缀,使之产生下一个前缀
ss[j] = ss[i];
ss[i] = temp;
permutation(ss, i + 1);// 4
temp = ss[j]; // 将前缀换回来,继续做上一个的前缀排列.//5
ss[j] = ss[i];
ss[i] = temp;
}
}
}
public static void gen(char[] ss) {
char[] opstr = new char[7];
opstr[0] = ss[0];
opstr[1] = ss[1];
ops[0] = ss[2];
ops[1] = ss[3];
int opcount = 0;
int curr = 2;
//循环产生所有的表达式组合,此处可以优化,少循环几次
for (int i = 0; i < ops.length; i++) {
opstr[curr++] = ops[i];
for (int j = 0; j < ops.length; j++) {
opstr[curr++] = ops[j];
for (int l = 0; l < ops.length; l++) {
opstr[curr++] = ops[l];
for (int m = 0; m < ops.length; m++) {
opstr[curr++] = ops[m];
for (int n = 0; n < ops.length; n++) {
opstr[curr++] = ops[n];
// 判断是否合法,运算符的数量是三个,数字两个且无重复,另外两个在开头,不用计算
opcount = 0;
for (int p = 2; p < opstr.length; p++) {
if (opstr[p] == '+' || opstr[p] == '-' || opstr[p] == '*' || opstr[p] == '/') {
opcount++;
}
}
if (opcount == 3) {
// 判断是否有重复数字
char exists = '0';
for (int p = 2; p < opstr.length; p++) {
if (opstr[p] >= '1' && opstr[p] <= '6') {
if (exists == '0')
exists = opstr[p];
else if (exists != '0' && exists == opstr[p]) {
exists = 'E';//E代表有重复了
break;
}
}
}
if (exists == '0' || exists != 'E') {
float re = calc(opstr);
System.out.println(new String(opstr) + "=" + re);
if (re > 0)
count++;
}
}
curr--;
}
curr--;
}
curr--;
}
curr--;
}
curr--;
}
}
public static float calc(char[] opstr) {
Stack<Float> temp = new Stack<>();
for(int i=0;i<opstr.length;i++) {
char c1 =opstr[i];
if (c1 > '0' && c1 <= '6') {
temp.push((int) (c1 - '0') + 0f);
} else {
// 运算符,每遇到一个运算符将计算栈里的数据
if (temp.size() >= 2) {
float t1 = temp.pop();
float t2 = temp.pop();
if (c1 == '+') {
temp.push(t1 + t2);
} else if (c1 == '-') {
temp.push(t2 - t1);
} else if (c1 == '*') {
temp.push(t1 * t2);
} else if (c1 == '/') {
temp.push(t2 / t1);
}
} else {
//如果栈里的数据不够,说明表达式错误
return -1f;
}
}
}
return temp.pop();
}
public static void main(String args[]) {
permutation(new char[] { '6', '5', '4', '1' }, 0);
System.out.println(count);
}
}