Программирование калькулятора, который выполняет операции в порядке DMAS - PullRequest
1 голос
/ 28 декабря 2011

Я создал программу калькулятора 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 ]

1 голос
/ 28 декабря 2011

В настоящее время у вас есть линейный подход к пониманию выражения, вы строите список операторов и выполняете их по порядку.

Вам нужно построить что-то более похожее на дерево, чтобы вы могли придать желаемый смысл

3 + 4 * 5

и вы, вероятно, тоже хотите разрешить скобки

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

Это очень распространенная проблема синтаксического анализа, обычно называемая анализом рекурсивного спуска.Вы сможете найти библиотеки, которые реализуют такие парсеры.Например, ANTLR .Это довольно большой скачок от того, где вы находитесь к такого рода вещам.Если вы покопаетесь вокруг, вы, вероятно, найдете простые реализации, которые вы можете клонировать, но если вы действительно хотите понять сферу, вам нужно немного изучить: такие статьи, как this , могут помочь.

0 голосов
/ 12 июля 2016

Хм, а если вы просто сохраните все символы, которые вы принимаете в качестве операндов и операторов, в связанном списке. Сохраните все операторы в массиве в соответствии с их приоритетом. Например, arr [] = {'/', '*', '+', '-'}, итерация по этим операторам. В то время как вы делаете это, обнаруживая любую из операций, которые должны быть применены в первую очередь, сохраняйте свой ответ в новом узле, затем удаляйте те узлы, которые содержат обнаруженные операции и операнды. Свяжите новый узел с узлом после последнего операнда, для какой операции был исполнен на. Вы можете повторять этот процесс до тех пор, пока следующий указатель базового или головного узла не станет равным нулю. И, честно говоря, я тоже новичок в этом вопросе, так что это решение, очевидно, не велико. Я тоже как-то думал, что это прямо сейчас, и, разумеется, сам не реализовал эту идею. Но да, вы можете сделать это, если хотите, хотя. Надеюсь, это поможет, хотя бы немного.

...