编程执行DMAS订单操作的计算器

时间:2011-12-28 06:49:53

标签: java calculator operator-precedence

我创建了一个GUI计算器程序,它以线性顺序执行计算,但我希望它按“除,乘,加,减”

的顺序执行计算。

我是初学者,所以请建议我是否有其他更简单的方法来实现我编码的相同内容。
请帮我解决'DMAS'事。

我的代码:

public class keypadGUI extends JFrame{
private JTextField lcd;
private JButton n1,n2,n3,n4,n5,n6,n7,n8,n9,n0;
private JButton plus,minus,multiply,divide,equalTo,dot;
//private JButton[] buttons = new JButton[10];
//private JButton[] opButtons = new JButton[6];
private double ans = 0;                     //For storing final ans
char[] op;                              //Character array for stroing operators
private double[] nums;                      //For storing the numbers
public JPanel keypad;
private StringBuilder sb = new StringBuilder();         //For storing the input of the user as string

public keypadGUI(){
    setLayout(new BorderLayout(10,10));
    lcd = new JTextField();
    lcd.setEditable(false);

    Border low = BorderFactory.createLoweredSoftBevelBorder();
    lcd.setBorder(low);
    lcd.setHorizontalAlignment(JTextField.RIGHT);
    lcd.setFont(new Font("Serif",Font.BOLD,30));
    lcd.setText("0");

    Font numFont = new Font("Serif",Font.BOLD,20);


    n1 = new JButton("1");  n2 = new JButton("2");  n3 = new JButton("3");  n4 = new JButton("4");
    n5 = new JButton("5");  n6 = new JButton("6");  n7 = new JButton("7");  n8 = new JButton("8");
    n9 = new JButton("9");  n0 = new JButton("0");  dot = new JButton(".");
    plus = new JButton("+");
    minus = new JButton("-");
    multiply = new JButton("*");
    divide = new JButton("/");
    equalTo = new JButton("=");
    n1.setFont(numFont);    n2.setFont(numFont);    n3.setFont(numFont);    n4.setFont(numFont);
    n5.setFont(numFont);    n6.setFont(numFont);    n7.setFont(numFont);    n8.setFont(numFont);
    n9.setFont(numFont);    n0.setFont(numFont);    dot.setFont(numFont);   plus.setFont(numFont);
    minus.setFont(numFont); multiply.setFont(numFont);  divide.setFont(numFont);    equalTo.setFont(numFont);

    plus.setForeground(Color.DARK_GRAY);        minus.setForeground(Color.DARK_GRAY);   multiply.setForeground(Color.DARK_GRAY);
    divide.setForeground(Color.DARK_GRAY);      equalTo.setForeground(Color.DARK_GRAY);

    listen listener = new listen();
    n1.addActionListener(listener); n2.addActionListener(listener); n3.addActionListener(listener); n4.addActionListener(listener);
    n5.addActionListener(listener); n6.addActionListener(listener); n7.addActionListener(listener); n8.addActionListener(listener);
    n9.addActionListener(listener); n0.addActionListener(listener); plus.addActionListener(listener);   minus.addActionListener(listener);
    multiply.addActionListener(listener);   divide.addActionListener(listener);
    equalTo.addActionListener(new equalListener());

    keypad = new JPanel(new GridLayout(4,4,10,10));
    keypad.add(n7); keypad.add(n8); keypad.add(n9); keypad.add(divide);
    keypad.add(n4); keypad.add(n5); keypad.add(n6); keypad.add(multiply);
    keypad.add(n1); keypad.add(n2); keypad.add(n3); keypad.add(plus);
    keypad.add(n0); keypad.add(dot);    keypad.add(equalTo);    keypad.add(minus);

    add(lcd,BorderLayout.NORTH);
    add(keypad,BorderLayout.CENTER);
    setVisible(true);
    setLookAndFeel();
    setSize(280,280);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setTitle("MY Calc");


}


private void setLookAndFeel(){
    try{
        for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    }catch(Exception ae){}
}

private class listen implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e){
            String bName = ((JButton)e.getSource()).getText();
            sb.append(bName);
            lcd.setText(sb.toString());
    }
}

private class equalListener implements ActionListener{
    public void actionPerformed(ActionEvent e){
        String[] tokkens = sb.toString().split("-|\\+|\\*|\\/");
        nums = new double[tokkens.length];
        for(int i=0;i<nums.length;i++){
            nums[i] = Double.parseDouble(tokkens[i]);
        }
        op = new char[10];
        op[0]='+';
        int c =1;
        for(int i=0;i<sb.length();i++){
            if(sb.charAt(i)=='+' || sb.charAt(i)=='-' || sb.charAt(i)=='*' || sb.charAt(i)=='/')
            {    op[c]=sb.charAt(i); c++; }
        }
        performOP();
        sb = sb.delete(0, sb.length());
        sb.append(ans);
        lcd.setText(sb.toString());


        System.out.println(op);
        System.out.println(Arrays.toString(tokkens));
    }
}

private void performOP(){
    for(int i=0;i<nums.length;i++){
        switch(op[i]){
            case '+':
                ans = ans + nums[i];
            break;
            case '-':
                ans = ans - nums[i];
            break;
            case '*':
                ans = ans * nums[i];
            break;
            case '/':
                ans = ans / nums[i];
            break;
            default:
            System.out.println("INVALID CASE !!!");
        }
    }
}
}

2 个答案:

答案 0 :(得分:1)

您目前使用线性方法来理解表达式,构建运算符列表并按顺序执行它们。

您需要构建更像树的东西,以便您可以将所需的含义赋予

3 + 4 * 5

你可能也想要括号

2 + ( 3 * 4) + ( 5 * ( 6 + 7 ) )

这是一个非常常见的解析问题,通常称为递归下降解析。您将能够找到实现此类解析器的库。例如ANTLR。从你到达这种东西,这是一个很大的跳跃。如果你四处寻找你可能会发现你可以克隆的简单实现,但是如果你真的想要理解这个领域,那么你需要学习很多东西:this这样的文章可能有所帮助。

答案 1 :(得分:-1)

嗯,如果您只是将所有作为操作数和运算符的字符存储在链表中,那该怎么办?根据优先级将所有运算符存储在数组中。例如,arr [] = {'/','*','+',' - '},遍历这些运算符。当您执行此操作时,首先检测需要应用的任何操作,将其答案存储在新节点中,然后删除包含检测到的操作和操作数的节点。将新节点链接到最后一个操作数之后的节点正在进行。您可以重复此过程,直到基本节点或头节点的下一个指针变为零。并且说实话,我也是这个问题的初学者,所以这个解决方案显然不是很好。我现在也有点想到这一点,并且我自己也没有实现这个想法。但是,如果你愿意的话,你可以试一试。希望它有所帮助,即使只是一点点。