Witam. Mam do napisania kalkulator który będzie obługiwał nawiasy i sprawdzał kolejność działań w skrócie ONP. Nie wiem za bardzo jak się za to zabrać :/ Czytałem na wikipedi ale nie bardzo kumam. Widziałem tez jakies przykłady ale tam były tylko liczby koło siebie ale 0 wytłumaczenia. Mógłby mi ktoś chętny i skory do pomocy objaśnić sens działania tego wszystkiego?? I jeszcze jedna sprawa, jak wprowadzam liczby (korzystam z buttomów) to chciałbym mieć np. 12 lub 321, to muszę każdą liczbę do tablicy zapisywać?? zrobić sobie jakąś ograniczoną tablicę, że można wpisywac tylko 9 cyfr (tablica 9 elementowa) czy jak jeszcze można?? A co najgorsze że to w JAVIE trzeba robić ;( więc chyba trochę trudniej jest. Za wszelką pomoc bardzo dziękuję i Pozdrawiam cieplutko wszystkich.
No tak, gdyby to było w C to byś miał gotowca: http://en.wikipedia.org/wiki/Shunting-yard_algorithm#C_example
I tak masz aplet w Javie pokazujący co się dzieje przy konwersji na ONP i liczeniu ONP: http://www.chris-j.co.uk/parsing.php
Myślę, że powinieneś sobie spokojnie poradzić. Napisz coś, pokaż kod, itd
ATSD: Zapisuj wszystko do Stringa jak leci, tzn najpierw zrób StringBuildera, potem dokładaj do niego znaki, a na końcu zrób na nim toString().
Ale ja to mam jako aplikację w JAVIE zrobić. Jak na razie tego nie rozumiem :/ czytałem o tym ale jakoś nie wchodzi. Ten przykład to jest jakiś dziwny (chodzi o gotowca c) ponieważ nie można w nim robić obliczeń tam jest tylko rozpisane jak to robić czy coś w tym stylu :/. Oj będzie ciężko.[Wczytane wyrażenie np(3+3)+3*1/2 to je posklejać do string`a?? a potem skonwertować na zmienną całkowitą?? czy do tablicy pakować po kolei co będize wciśnięte?? program ma być z użciem buttomów a nie że się wpisuje do textfielda i tylko pobrać. to jest moim zdaniem wielkie utrudnienie :/Pozdrawiam
Wielce mi utrudnienie. Po kliknięciu Buttona po prostu dodajesz znak do Stringa w TextFieldzie, cóż to za problem?
Czyli jest np zmienna typu string np. wyrażenei i potem z niej konwertuje do int czy tam innego typu?? jak sprawdzać po kolei jaki jest znak. Musi być jakas tablica przecież.
Masz metodę String.charAt(int index). Ewentualnie metoda String.toCharArray().
Prawdopodobnie będzie pomocne: http://www.algorytm.org/algorytmy-arytmetyczne/odwrotna-notacja-polska.html
Pozdrawiam
ps. Dodatkowo znajduję się tam gotowa implementacja, możesz ją przeanalizować.
Może też to Cię zainteresuje przy okazji:
A to już gotowiec z tłumaczeniem:
http://kodatnik.blogspot.com/2009/12/odwrotna-notacja-polska-czesc-1.html
Gotową bibliotekę masz tutaj:
http://code.google.com/p/rpncalculator/
Dziękuje wszystkim za linki. Na pewno już sobie z tym poradzę :) dużo tego mam więc myślę, że nie będzie problemu. Ale nurtuje mnie 1 pytanie. Widziałem dużo programów z ONP ale nie napotkałem się na wynik z działania, tylko był podany
na wejściu wyrażenie infiksowe, a na wyjściu wyrażenie postfiksowe. Jak to zrobić żęby z tego postfiskowego był normalny wynik z tego działąnia?? .
Nigdzie tego nie ma bo to jest banalne i można to zaklepać w 20 min. Jeżeli masz podane wyrażenie w ONP to gdy trafiasz na liczbę to kładziesz na stos (np ArrayList), a jeżeli trafisz na operator to wyciągasz dwie liczby ze stosu (czy tam ile ten operator potrzebuje), wykonujesz działanie i wynik kładziesz z powrotem na stos. Po wykonaniu całego wyrażenia ostateczny wynik będzie jedynym elementem w stosie.
Co tu wiele pisać. Masz tu przykład klasy, którą kiedyś napisałem.
package kalkulator2;
import java.util.*;
public class ONP
{
private String wyrazenie;//zawiera wyrażenie w pierwotnej postaci
private String onp;//wyrażenie w odwrotnej notacji polskiej
private String nieLiczby="+-*/^()";
/**
Stwórz obiekt, który dokona konwersji wyrażenia na odwrotną notację polską.
- @param wyrazenie
- oznacza wyrażenie które ma zostac skonwertowane do odwrotnej notacji polskiej.
/
public ONP(String wyrazenie) {
this.wyrazenie = wyrazenie;
onp = "";
toONP();//wywołaj konwersję wyrażenia na oonp
}
/* - Konwersja wyrażenia na odwrotną notację polską.
- 1 - dzielimy wyrażenie infiksowe na części na podstawie separatorów
- 2 - dopóki są elementy w wyrażeniu wejściowym
- 2.1 - pobieramy element
- 2.2 - jeżeli element jest operatorem
- 2.2.1 - sprawdzemy priorytety
- 2.2.2 - odkładamy operator na stos
- 2.3 - jeżeli element jest nawiasem otwierającym
- 2.3.1 - odłóż na stos nawias otwierający
- 2.4 - jeżeli element jest nawiasem zamykającym
- 2.4.1 - ściągamy operatory ze stosu, aż do nawiasu otwierajęcego
- 2.4.2 - ściągnij ze stosu
- 2.4.3 - ściągnij już niepotrzebny nawias otwierający
- 2.5 - jeżeli element nie jest operatorem ani nawiasem dodajemy go do wyrażenia postfiksowego
- 3 - ściągamy ze stosu pozostałe operatory i dodajemy je do wyrażenia postfiksowego
- 3.1 - ściągnij i dopisz do wyrażenia onp
@param wyrazenie - dokonuje konwersji wyrażenia na ONP.
/
private void toONP()
{
// eliminateNakedMinus();
Stack<String> stos = new Stack<String>();
StringTokenizer st = new StringTokenizer(wyrazenie, "+-/^()", true);//1
while(st.hasMoreTokens()) //2
{
String s = st.nextToken();//2.1
if( s.equals("+") || s.equals("*") || s.equals("-") || s.equals("/") || s.equals("^")) //2.2
{
while(!stos.empty() && priorytet(stos.peek()) >= priorytet(s))//2.2.1
{
onp += stos.pop() + " ";
}
stos.push(s);//2.2.2
}
else if(s.equals("(")) //2.3
{
stos.push(s);//2.3.1
}
else if(s.equals(")"))//2.4
{
while(!stos.peek().equals("(")) //2.4.1
{
onp += stos.pop() + " ";//2.4.2
}
stos.pop();//2.4.3
}
else //2.5
{
onp += s + " ";
}
}
while(!stos.empty())//3
{
onp += stos.pop() + " ";//3.1
}
}
/**
- Obliczenie priorytetu operatora:
-
- lub - = 1
-
- lub / = 2
- ^ = 3
- pozostałe = 0
- @param operator
- operator, dla którego zostanie wyznaczony priorytet.
- @return
*/
private boolean czyNieLiczba(char z)
{
for(int i=0;i<nieLiczby.length();i++)
{
if(nieLiczby.charAt(i)==z)
{
return true;
}
}
return false;
}
public static int priorytet(String operator)
{
if(operator.equals("+") || operator.equals("-")) {return 1;}
else if(operator.equals("*") || operator.equals("/")) {return 2;}
else if(operator.equals("^")){return 3;}
else {return 0;}//pozostałe 0
}
/**
- Zwróć wyrażenie w postaci Odwrotnej Notacji Polskiej
/
public @Override String toString() //zwróć wyrażenie w postaci onp
{
return onp;
}
/*
-
Dokonaj obliczenia zapisanego w odwrotnej notacji polskiej i zwróć wynik.
-
@return
-
Zwraca wynik z zapisanego wyrażenia w postaci ONP.
*/
public double oblicz()
{String wejscie = onp+" =";
Stack<Double> stos = new Stack<Double>();//przechowuje wyniki pośrednie
double a=0;//przechowuje dane ze stosu
double b=0;//przechowuje dane ze stosu
double w=0;//wynik operacji arytmetycznej
String buduj="";
String spacja=" ";
char sp=' ';int licznik=0;
do{//Krok 1: Czytaj el z we
char czar=wejscie.charAt(licznik);
if(czar=='+' || czar == '-' || czar == '' || czar == '/' || czar == '^')//Krok 2: Jeśli el nie jest liczbą, to idź do kroku 5
{
if(!stos.empty()){
b=stos.pop();//Krok 6: Pobierz ze stosu dwie liczby a i b
a=stos.pop();
if(czar=='+'){w=a+b;}//Krok 7: Wykonaj nad liczbami a i b operację określoną przez el i umieść wynik w w
else if(czar=='-'){w=a-b;}
else if(czar==''){w=ab;}
else if(czar=='/'){w=a/b;}
else if(czar=='^')
{
if(b==0)
{
w=1;
}
else
{
w=a;
int licz=1;
while(licz<(int)b)
{
w=w;
licz++;
}
}
}stos.push(w);//Krok 8: Umieść w na stosie } } else if(czar == sp)//Krok 3: Umieść el na stosie { if(buduj.compareTo("")!=0){ double tmp = Double.parseDouble(buduj); stos.push(tmp); buduj=""; } } else if(czar=='=')//Krok 5: Jeśli el jest znakiem '=', to idź do kroku 10 { if(!stos.empty()){ w=stos.pop();//Krok 10: Prześlij na wyjście zawartość wierzchołka stosu break; } } else if(czar>='0' && czar <='9')//buduj liczbe { buduj+=czar; } licznik++;
}while(licznik<wejscie.length());//Krok 4: Idź do kroku 1
return w;
}
}
Mam jesycye jedn spraw, a mianowicie chodyi o to pobieram tekst wpisanz do ymiennej String z jTextField-a i potem chcę skonwertować do zmiennej "int" ale wyskakuje mi podczas pracy programu mnÓstwo błędów :/ jak to skonwertować ?? ja robię integer.parseint().