給出四個數字,要求,在其間添加運算符和括號,使得計算結果等於24。
括號的放置即為決定哪幾個數先進行計算。所以,我們先確定首先進行計算的兩個相鄰的數,計算完成后,就相當於剩下三個數字,仍需要在它們之間添加符號;然后再決定在這三個數中哪兩個相鄰的數先計算。由此,我們就成功解決了數字的運算次序問題,此時不需要再考慮不同運算符號的優先級問題,因為括號的優先級高於加減乘除。
通過循環,我們可以得到第一第二第三次計算的運算符,再通過計算,就可以得出和,若和等於24,即為所求解。
在輸出格式中,由於括號的放置共六種情況,故根據計算先后順序的不同,輸出時在不同地方放置括號;
以下是java源碼:
import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.util.*; import javax.swing.JOptionPane; public class TwentyFourPoke_Game extends JFrame { private JButton jbsolution = new JButton("Find a Solution"); private JButton jbrefresh = new JButton("Refresh"); private JButton jbverify = new JButton("Verify"); private JLabel jlmessage = new JLabel("Enter an expression:"); private JTextField jtsolution = new JTextField(); private JTextField jtexpression = new JTextField(); private ImagePanel pp = new ImagePanel(); private int[] card = new int[4]; private double[] bcard = new double[4]; private double sum; private double[] temp1 = new double[3]; private double[] temp2 = new double[2]; private char[] sign = {'+','-','*','/'}; public TwentyFourPoke_Game() { JPanel p1 = new JPanel(new GridLayout(1,3)); p1.add(jbsolution); p1.add(jtsolution); p1.add(jbrefresh); JPanel p3 = new JPanel(new GridLayout(1,3)); p3.add(jlmessage); p3.add(jtexpression); p3.add(jbverify); add(p1,BorderLayout.NORTH); add(pp,BorderLayout.CENTER); add(p3,BorderLayout.SOUTH); ButtonListener listener = new ButtonListener(); jbsolution.addActionListener(listener); jbrefresh.addActionListener(listener); jbverify.addActionListener(listener); } class ButtonListener implements ActionListener { public void actionPerformed(ActionEvent e) { if(e.getSource() == jbsolution) { for(int i = 0;i < 4;i++) { bcard[i] = (double)card[i] % 13; if(card[i] % 13 == 0) bcard[i] = 13; } search(); } else if(e.getSource() == jbrefresh) { pp.sshow(); } else if(e.getSource() == jbverify) { String expression = jtexpression.getText(); int result = evaluateExpression(expression); if(result == 24) { JOptionPane.showMessageDialog(null,"恭喜你!你答對了!","消息框",JOptionPane.INFORMATION_MESSAGE); } else { JOptionPane.showMessageDialog(null,"抱歉!請再次嘗試。","消息框",JOptionPane.INFORMATION_MESSAGE); } } } } public static double calcute(double a,double b,char c) { if(c == '+') return a+b; else if(c == '-') return a-b; else if(c == '*') return a*b; else if(c == '/' && b != 0) return a/b; else return -1; } public void search() { boolean judge = false; for(int i=0;i<4;i++) //第一次放置的符號 { for(int j=0;j<4;j++) //第二次放置的符號 { for(int k=0;k<4;k++) //第三次放置的符號 { for(int m=0;m<3;m++) //首先計算的兩個相鄰數字,共有3種情況,相當於括號的作用 { if(bcard[m+1]==0 && sign[i]=='/') break; temp1[m]=calcute(bcard[m],bcard[m+1],sign[i]); temp1[(m+1)%3]=bcard[(m+2)%4]; temp1[(m+2)%3]=bcard[(m+3)%4]; //先確定首先計算的兩個數字,計算完成相當於剩下三個數,按順序儲存在temp數組中 for(int n=0;n<2;n++) //三個數字選出先計算的兩個相鄰數字,兩種情況,相當於第二個括號 { if(temp1[n+1]==0 && sign[j]=='/') break; temp2[n]=calcute(temp1[n],temp1[n+1],sign[j]); temp2[(n+1)%2]=temp1[(n+2)%3]; //先確定首先計算的兩個數字,計算完成相當於剩下兩個數,按順序儲存在temp數組中 if(temp2[1]==0 && sign[k]=='/') break; sum=calcute(temp2[0],temp2[1],sign[k]); //計算和 if(sum==24) //若和為24 { judge=true; //判斷符為1,表示已求得解 if(m==0 && n==0) { String sss ="(("+(int)bcard[0]+sign[i]+(int)bcard[1]+")"+sign[j]+(int)bcard[2]+")"+sign[k]+(int)bcard[3]+"="+(int)sum; jtsolution.setText(sss); return ; } else if(m==0 && n==1) { String sss ="("+(int)bcard[0]+sign[i]+(int)bcard[1]+")"+sign[k]+"("+(int)bcard[2]+sign[j]+(int)bcard[3]+")="+(int)sum; jtsolution.setText(sss); return ; } else if(m==1 && n==0) { String sss ="("+(int)bcard[0]+sign[j]+"("+(int)bcard[1]+sign[i]+(int)bcard[2]+"))"+sign[k]+(int)bcard[3]+"="+(int)sum; jtsolution.setText(sss); return ; } else if(m==2 && n==0) { String sss ="("+(int)bcard[0]+sign[j]+(int)bcard[1]+")"+sign[k]+"("+(int)bcard[2]+sign[i]+(int)bcard[3]+")="+(int)sum; jtsolution.setText(sss); return ; } else if(m==2 && n==0) { String sss =(int)bcard[0]+sign[k]+"("+(int)bcard[1]+sign[j]+"("+(int)bcard[2]+sign[i]+(int)bcard[3]+"))="+(int)sum; jtsolution.setText(sss); return ; } //m=0,1,2 n=0,1表示六種括號放置可能,並按照這六種可能輸出相應的格式的計算式 } } } } } } if(judge==false) jtsolution.setText("No solution!"); //如果沒有找到結果,符號位為0 } public static int evaluateExpression(String expression) { // Create operandStack to store operands java.util.Stack<Integer> operandStack = new java.util.Stack<Integer>(); // Create operatorStack to store operators java.util.Stack<Character> operatorStack = new java.util.Stack<Character>(); // Extract operands and operators java.util.StringTokenizer tokens = new java.util.StringTokenizer(expression, "()+-/*", true); // Phase 1: Scan tokens while (tokens.hasMoreTokens()) { String token = tokens.nextToken().trim(); // Extract a token if (token.length() == 0) // Blank space continue; // Back to the while loop to extract the next token else if (token.charAt(0) == '+' || token.charAt(0) == '-') { // Process all +, -, *, / in the top of the operator stack while (!operatorStack.isEmpty() &&(operatorStack.peek().equals('+') ||operatorStack.peek().equals('-') || operatorStack.peek().equals('*') || operatorStack.peek().equals('/'))) { processAnOperator(operandStack, operatorStack); } // Push the + or - operator into the operator stack operatorStack.push(new Character(token.charAt(0))); } else if (token.charAt(0) == '*' || token.charAt(0) == '/') { // Process all *, / in the top of the operator stack while (!operatorStack.isEmpty() && (operatorStack.peek().equals('*') || operatorStack.peek().equals('/'))) { processAnOperator(operandStack, operatorStack); } // Push the * or / operator into the operator stack operatorStack.push(new Character(token.charAt(0))); } else if (token.trim().charAt(0) == '(') { operatorStack.push(new Character('(')); // Push '(' to stack } else if (token.trim().charAt(0) == ')') { // Process all the operators in the stack until seeing '(' while (!operatorStack.peek().equals('(')) { processAnOperator(operandStack, operatorStack); } operatorStack.pop(); // Pop the '(' symbol from the stack } else { // An operand scanned // Push an operand to the stack operandStack.push(new Integer(token)); } } // Phase 2: process all the remaining operators in the stack while (!operatorStack.isEmpty()) { processAnOperator(operandStack, operatorStack); } // Return the result return ((Integer)(operandStack.pop())).intValue(); } public static void processAnOperator(java.util.Stack<Integer> operandStack,java.util.Stack<Character> operatorStack) { if (operatorStack.peek().equals('+')) { operatorStack.pop(); int op1 = ((Integer)(operandStack.pop())).intValue(); int op2 = ((Integer)(operandStack.pop())).intValue(); operandStack.push(new Integer(op2 + op1)); } else if (operatorStack.peek().equals('-')) { operatorStack.pop(); int op1 = ((Integer)(operandStack.pop())).intValue(); int op2 = ((Integer)(operandStack.pop())).intValue(); operandStack.push(new Integer(op2 - op1)); } else if (operatorStack.peek().equals('*')) { operatorStack.pop(); int op1 = ((Integer)(operandStack.pop())).intValue(); int op2 = ((Integer)(operandStack.pop())).intValue(); operandStack.push(new Integer(op2 * op1)); } else if (operatorStack.peek().equals('/')) { operatorStack.pop(); int op1 = ((Integer)(operandStack.pop())).intValue(); int op2 = ((Integer)(operandStack.pop())).intValue(); operandStack.push(new Integer(op2 / op1)); } } class ImagePanel extends JPanel { public void sshow() { int i; for(i = 0;i < 4;i++) { card[i] = (int)(1 + Math.random() * 52); } repaint(); } protected void paintComponent(Graphics g) { super.paintComponent(g); int i; int w = getWidth() / 4; int h = getHeight(); int x = 0; int y = 0; for(i = 0;i < 4;i++) { ImageIcon imageIcon = new ImageIcon("image/card/" + card[i] + ".png"); Image image = imageIcon.getImage(); if(image != null) { g.drawImage(image,x,y,w,h,this); } x += w; } } } public static void main(String[] args) { TwentyFourPoke_Game frame = new TwentyFourPoke_Game(); frame.setTitle("24 Poke Game"); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(368,200); frame.setVisible(true); } }