📄 twentyfour.java
字号:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class TwentyFour extends JFrame implements ActionListener {
/** Create a new instance of GUI */
Font font = new Font("华文细黑", Font.PLAIN, 30);// BOLD黑体,ITALIC斜体,PLAIN普通模式
JLabel tip = new JLabel("请输入:");
JTextField one = new JTextField(3);
JTextField two = new JTextField(3);
JTextField three = new JTextField(3);
JTextField four = new JTextField(3);//四个输入框
JButton button1 = new JButton("组合");
JButton button2 = new JButton("清空结果");
JButton button3 = new JButton("清空所有");//三个按钮
JTextArea display = new JTextArea("牛牛制作",5, 15);//显示区
String[] number = new String[4];
int[] factor = new int[4];
boolean[] b = new boolean[4];
final String[] sign = { "+", "-", "*", "/" };// 符号
String[] use = new String[3];// 使用的三个符号
final String[] example = { "00-0-0-", "00-00--", "000--0-", "000-0--",
"0000---" };// 能生成的几种后缀表达式的样子
public TwentyFour() {
super("二十四点自动组合");
Container container = getContentPane();
JPanel panel1 = new JPanel();
panel1.add(tip);
panel1.add(one);
panel1.add(two);
panel1.add(three);
panel1.add(four);
JPanel panel2 = new JPanel();
panel2.add(button1);
panel2.add(button2);
panel2.add(button3);
container.add(panel1, BorderLayout.NORTH);
container.add(panel2, BorderLayout.CENTER);
container.add(new JScrollPane(display),BorderLayout.SOUTH);
display.setFont(font);
display.setBackground(Color.cyan);
setVisible(true);//窗体可见
setSize(400, 320);//窗体大小
setLocation(400, 400);//窗体显示在屏幕位置
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗体后退出程序
//按钮点击事件
button1.addActionListener(this);
button2.addActionListener(this);
button2.setEnabled(false); //无数值组合button2清空结果不可用
button3.addActionListener(this);
button3.setEnabled(false); //初始时button3初始无效
}
public void actionPerformed(ActionEvent e) {
String result = getResult();
button1.setEnabled(true); //初始时button1可用
if (e.getSource() == button1) {
if (result.length() != 0){
display.setText(result);
button1.setEnabled(false); //组合成功后button1组合不可用
button2.setEnabled(true); //组合成功后button2清空结果可用
button3.setEnabled(true); //组合成功后button3初始化可用
}
else
display.setText("不能组合成24!\n请重新输入!");
}
else if (e.getSource() == button2) {
display.setText(null);
button1.setEnabled(true); //清空结果后button1组合可用
button2.setEnabled(false); //清空结果后button2清空结果不可用
button3.setEnabled(true); //清空结果后button3初始化可用
}
else if (e.getSource() == button3) {
one.setText(null);
two.setText(null);
three.setText(null);
four.setText(null);
display.setText(null);
button2.setEnabled(false);
button3.setEnabled(false); //还原成初始状态
}
}
// 获得结果
public String getResult() {
StringBuffer buffer = new StringBuffer();
number[0] = one.getText();
number[1] = two.getText();
number[2] = three.getText();
number[3] = four.getText();
Arrays.fill(b, true);
for (int i = 0; i < 4; i++)
factor[i] = i;
while (true) {
postfix(buffer);// 根据4个数的顺序,生成表达式,并获得结果
int j = 3;
// 生成4个数的所有排列组合
for (; j > 0; j--) {
b[factor[j]] = false;
if (factor[j] > factor[j - 1]) {
for (int k = factor[--j]; k < 4; k++) {
if (!b[k]) {
b[factor[j]] = false;
factor[j++] = k;
b[k] = true;
break;
}
}
for (int k = 0; k < 4 && j < 4; k++) {
if (!b[k]) {
factor[j++] = k;
b[k] = true;
}
}
break;
}
}
// System.out.println(buffer);
if (j == 0)
break;
}
return new String(buffer);
}
// 生成后缀表达式
public void postfix(StringBuffer buffer) {
String[] temp = new String[7];
// 生成后缀表达式的方法很垃圾,用了多重循环
for (int j1 = 0; j1 < 4; j1++) {
use[0] = sign[j1];
for (int j2 = 0; j2 < 4; j2++) {
use[1] = sign[j2];
for (int j3 = 0; j3 < 4; j3++) {
use[2] = sign[j3];
for (int i = 0; i < example.length; i++) {
int k = 0, x = 0;
for (int j = 0; j < 7; j++) {
if (example[i].charAt(j) == '0')
temp[j] = number[factor[k++]];
else
temp[j] = use[x++];
}
double result = calculate(temp);
if (result < 24.0000001 && result > 23.9999999) {
// 如果计算的结果等于24,那么就转成中缀表达式
String judge = postToCenter(temp, temp.length - 1,
0) + "=24" + '\n';
if (buffer.indexOf(judge) < 0)
buffer.append(judge);
}
}
}
}
}
}
// 计算后缀表达式的结果
public double calculate(String[] postfix) {
double[] result = new double[4];
for (int i = 0, j = 0; i < 7; i++) {
// 判断是否为操作数
if (Character.isDigit(postfix[i].charAt(postfix[i].length() - 1)))
result[j++] = Integer.parseInt(postfix[i]);
else {
double t = cal(result[j - 2], result[j - 1], postfix[i]
.charAt(0));
if (t == Double.MAX_VALUE)
return 0;
result[j-- - 2] = t;
}
}
return result[0];
}
// 计算两个数在相应的运算符下的结果
public double cal(double a, double b, char c) {
switch (c) {
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
if (b == 0)
return Double.MAX_VALUE;// 除数为0,返回一个值,表明该表达式无法计算得24
return a / b;
default:
return 0;
}
}
// 后缀表达式转中缀表达式,利用了递归的方法,利用了后缀表达式可以化成ppo的样子
public static String postToCenter(String[] postfix, int end, int priority) {
if (end == 0
|| Character.isDigit(postfix[end]
.charAt(postfix[end].length() - 1)))
return postfix[end];
StringBuffer buffer = new StringBuffer();
char s = postfix[end].charAt(0);
// 赋给运算符一定的优先级
if (s == '+' || s == '-')
s = 40;
else
s = 50;
// 找到下一个p的位置
int k = end - 1;
for (int j = 0; k >= 0; k--) {
if (Character.isDigit(postfix[k].charAt(postfix[k].length() - 1)))
j++;
else
j--;
if (j == 1)
break;
}
if (s < priority)
buffer.append('(');
buffer.append(postToCenter(postfix, k - 1, s));
buffer.append(postfix[end--]);
buffer.append(postToCenter(postfix, end, s));
if (s < priority)
buffer.append(')');
return new String(buffer);
}
public static void main(String[] args) {
new TwentyFour();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -