Operatory arytmetyczne

0

Cześć piszę kalkulator i potrzebuję pomocy, a mianowicie co zrobić żeby w moim kalkulatorze trzeba było użyć 2 operatorów czyli np + i - w jednym działaniu, kalkulator pobiera od użytkownika 3 liczby, ale stoję w miejscu z tymi operatorami. Ma ktoś pomysł jak to zrobić ?

0

Użytkownik podaję liczby, wybiera operator, otrzymuje wynik, wybiera kolejny operator, wpisuje liczbę, otrzymuje wynik finalny

0

Jak Mozna to Użyj nawiasów.

1

Dobrze można to zrobić tylko w jeden sposób.

  1. Użyszkodnik podaje wyrażenie do obliczenia
  2. Oddzielasz ziarna od plew czyli operatory od operandów
  3. Obliczasz wartość wyrażenia uwzględniając priorytety operatorów nawiasy, etc.
  4. Obliczoną wartość zwracasz użytkownikowi

Zakładam, że z punktami 1 i 4 nie będziesz miał problemów.
Punkt drugi - piszesz parser, który kwalifikuje czy coś jest operatorem, np: +, -, ^, etc czy operandem, np: 3, 3.14, etc. W prostych przypadkach nawet if/switch wystarczy.
Punkt trzeci - jest kilka sposobów jak to zrobić, można przetransformować do odwrotnej notacji polskiej lub użyć/napisać parser, który to obliczy.

Ponieważ odwrotną notację polską polecają wszyscy to ja zaproponuję ci troszkę inny sposób. Z tego co pamiętam (ale mogę się mylić) to jest to przykład obliczenia wyrażanie metodą shift-reduce dla podstawowych działań arytmetycznych. Wstydzę się trochę tego kodu (pisałem go lata temu) ale powinien ci mniej więcej zobrazować o co chodzi:

public enum Operator {
    PLUS {
        int prior() {return 1;};
        double eval(double x, double y) {
            return x + y;
        }
    },
    MINUS {
        int prior() {return 1;};
        double eval(double x, double y) {
            return x - y;
        }
    },
    TIMES {
        int prior() {return 2;};
        double eval(double x, double y) {
            return x * y;
        }
    },
    DIVIDE {
        int prior() {return 2;};
        double eval(double x, double y) {
            return x / y;
        }
    };
    abstract double eval(double x, double y);
    abstract int prior();
}

----------------------------

import java.util.Stack;
import java.util.StringTokenizer;

public class Kalkulator {

    /*public static void main(String[] args) {

         System.out.println(Kalkulator.calculate(args[0]));

    }*/

    public static double calculate(String expression) throws InvalidExpressionException{

        Stack<Double> vStack = new Stack<Double>();  //stos wartosci
        Stack<Operator> oStack = new Stack<Operator>(); // stos operatorow
        Operator temp = null;                           //tymczasowy operator
        Operator current;                               //aktualny operator
        double v1, v2;                                  //operandy

        try {
            StringTokenizer st = new StringTokenizer(expression, "+-*/", true);
            int dim = st.countTokens();                    //wymiar tablicy wyrazen
            String [] tokens = new String[dim];             //tablica wyrazen
            for(int i = 0;i<dim;i++) {                      //podzial wyrazenia na tokeny
                tokens[i] = st.nextToken();
            }

            /*wczytujemy kolejne elementy wyrazenia, jezeli wczytany token jest 
             * liczba to wrzucamy go na stos wartosci. Jezeli jest operatorem 
             * to sprawdzamy czy ma wyzszy priorytet niz operator na stosie.
             * jezeli nie to  wrzucamy go na stos. jezeli tak to zdejmujemy ze 
             * stosu wartosci dwie kolejne liczby i wywołujemy eval(), rezultat
             * wrzucamy na stos.
             */
            for (int i=0; i<tokens.length; i++) {
                 switch (tokens[i]) {
                 case "+" : temp = Operator.PLUS; break;    
                 case "-" : temp = Operator.MINUS; break;
                 case "*" : temp = Operator.TIMES; break;
                 case "/" : temp = Operator.DIVIDE; break;
                 default: vStack.push(Double.parseDouble(tokens[i])); break;
                 }
                 if (temp == null) continue;
                 while (!(oStack.empty() || oStack.peek().prior() < temp.prior() )) {
                     v2 = vStack.pop();
                     v1 = vStack.pop();
                     current = oStack.pop();
                     vStack.push(current.eval(v1, v2));
                 }
                 oStack.push(temp);
                 temp = null; 
             }
            /*Po dojsciu do konca tablicy oprozniamy stos operatorow, wynik dzialania
             * eval wrzucamy na stos wartosci.
             * Rezulatatem koncowym jest liczba na stosie wartosci
             */
             while (!oStack.empty() ) {
                 v2 = vStack.pop();
                 v1 = vStack.pop();
                 current = oStack.pop();
                 vStack.push(current.eval(v1, v2));
             }
            return vStack.pop();
        } catch (Exception e) {
            throw new InvalidExpressionException();
        }
    }

}
0

Tutaj: https://4programmers.net/Forum/C_i_C++/302838-przerobienie_kodu?p=1440033#id1440033 jest opis algorytmu, jak ewaluować dowolne wyrażenie arytmetyczne.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0