/**
* Trieda reprezentujuca aritmeticky vyraz
*/
public class Vyraz {
/**
* Rozhranie, ktore implementuju vsetky uzly aritmetickeho stromu
*/
private interface Clen {
@Override
public String toString();
}
/**
* Trieda implementujuca uzol stromu aritmetickeho stromu, ktory
* reprezentuje binarnu operaciu
*/
private static class BinarnaOperacia implements Clen {
private char operator;
private Clen lavyPodvyraz;
private Clen pravyPodvyraz;
public BinarnaOperacia(char operator, Clen lavy, Clen pravy) {
this.operator = operator;
this.lavyPodvyraz = lavy;
this.pravyPodvyraz = pravy;
}
@Override
public String toString() {
return "(" + lavyPodvyraz.toString() + operator
+ pravyPodvyraz.toString() + ")";
}
}
/**
* Trieda implementujuca uzol aritmetickeho stromu, ktory reprezentuje
* konstantu
*/
private static class Hodnota implements Clen {
private double hodnota;
public Hodnota(double hodnota) {
this.hodnota = hodnota;
}
@Override
public String toString() {
return Double.toString(hodnota);
}
}
/**
* Symboly operacii od najnizsej priority po najvyssiu
*/
private static final String SYMBOLY_OPERACII = "+-*/";
/**
* Prevedie zadany vyraz do aritmetickeho stromu
*
* @param vyraz
* vyraz, ktory sa ma parsovat
* @return referencia na koren aritmetickeho stromu
*/
private static Clen prevedNaStrom(String vyraz) {
// Odstranime zbytocne medzery
vyraz = vyraz.trim();
// Najdeme operator s najnizsou prioritou, ktory nie je v zatvorkach
int operatorIdx = Integer.MAX_VALUE;
int operatorPoz = -1;
int pocitadloZatvoriek = 0;
for (int i = 0; i < vyraz.length(); i++) {
char znak = vyraz.charAt(i);
if (znak == '(')
pocitadloZatvoriek++;
if (znak == ')')
pocitadloZatvoriek--;
int priorita = SYMBOLY_OPERACII.indexOf(znak);
if ((priorita != -1) && (pocitadloZatvoriek == 0) && (i > 0)) {
if (priorita <= operatorIdx) {
operatorIdx = priorita;
operatorPoz = i;
}
}
}
// Rozdelime vyraz na podvyrazy
if (operatorPoz != -1) {
return new BinarnaOperacia(SYMBOLY_OPERACII.charAt(operatorIdx),
prevedNaStrom(vyraz.substring(0, operatorPoz)),
prevedNaStrom(vyraz.substring(operatorPoz + 1)));
}
// Poznamka: Ak sme nenasli operator, tak je to alebo konstanta, alebo
// cely vyraz je ozatvorkovany
// Ak je cely vyraz ozatvorkovany, tak nechame rozparsovat jeho vnutornu
// cast
if ((vyraz.charAt(0) == '(')
&& (vyraz.charAt(vyraz.length() - 1) == ')'))
return prevedNaStrom(vyraz.substring(1, vyraz.length() - 1));
// Ak sme tu, tak to musi byt cislo
try {
return new Hodnota(Double.parseDouble(vyraz));
} catch (NumberFormatException e) {
throw new RuntimeException(
"Zadany vyraz nie je korektny aritmeticky vyraz");
}
}
/**
* Koren aritmetickeho stromu vyrazu
*/
private Clen koren;
/**
* Skontruuje novy aritmeticky vyraz
*
* @param vyraz
* retazec s aritmetickym vyrazom
*/
public Vyraz(String vyraz) {
koren = prevedNaStrom(vyraz);
}
@Override
public String toString() {
return koren.toString();
}
public static void main(String[] args) {
Vyraz v = new Vyraz("(-3)+6/2+3*2");
System.out.println(v);
}
}