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ć ?
- Rejestracja:ponad 7 lat
- Ostatnio:około 7 lat
- Postów:7

- Rejestracja:około 11 lat
- Ostatnio:ponad rok
- Postów:182
Dobrze można to zrobić tylko w jeden sposób.
- Użyszkodnik podaje wyrażenie do obliczenia
- Oddzielasz ziarna od plew czyli operatory od operandów
- Obliczasz wartość wyrażenia uwzględniając priorytety operatorów nawiasy, etc.
- 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();
}
}
}


- Rejestracja:około 8 lat
- Ostatnio:4 minuty
- Postów:4927
Tutaj: https://4programmers.net/Forum/C_i_C++/302838-przerobienie_kodu?p=1440033#id1440033 jest opis algorytmu, jak ewaluować dowolne wyrażenie arytmetyczne.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.
Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.