//分享一段計算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);
}
}