Odwrotna notacja polska



Pobieranie 28,9 Kb.
Data21.06.2018
Rozmiar28,9 Kb.

Odwrotna notacja polska


Odwrotna notacja polska inaczej RPN (ang. Reverse Polish Notation) - jest sposobem zapisu wyrażeń arytmetycznych w którym znak wykonywanej operacji umieszczony jest po operandach (zapis postfiksowy), a nie pomiędzy nimi jak w konwencjonalnym zapisie algebraicznym (zapis infiksowy). Zapis ten pozwala na całkowitą rezygnację z użycia nawiasów w wyrażeniach, jako że jednoznacznie określa kolejność wykonywanych działań.

RPN bardzo ułatwia wykonywanie na komputerze obliczeń z nawiasami i zachowaniem kolejności działań. Zarówno algorytm konwersji notacji konwencjonalnej (infiksowej) na odwrotną notację polską (postfiksową), jak i algorytm obliczania wartości wyrażenia danego w RPN są bardzo proste i wykorzystują stos.

Odwrotna notacja polska została opracowana przez australijskiego naukowca Charlesa Hamblina jako "odwrócenie" beznawiasowej notacji polskiej Jana Łukasiewicza na potrzeby zastosowań informatycznych. Hamblin sugerował aby notację tą nazwać "Zciweisakul notation" (Notacja Azciweisakuł - "Łukasiewcz" pisane od tyłu).

Jest używana w niektórych językach programowania (FORTH, Postscript) oraz w kalkulatorach naukowych firmy Hewlett-Packard. Programy komputerowe dokonując analizy wyrażenia arytmetycznego często przekształcają je na odwrotną notację polską.


Przykłady zapisu


Przykładowy konwencjonalny zapis: (2+3)*5

w RPN wygląda tak: 2 3 + 5 *

natomiast: ((2+7)/3+(14-3)*4)/2

zapiszemy następująco: 2 7 + 3 / 14 3 - 4 * + 2 /


Algorytm obliczenia wartości wyrażenia RPN


  1. wyzeruj stos

  2. dla wszystkich symboli z wyrażenia RPN wykonuj:

    1. jeśli i-ty symbol jest liczbą, to odłóż go na stos

    2. jeśli i-ty symbol jest operatorem to:

      1. zdejmij ze stosu jeden element (ozn. a)

      2. zdejmij ze stosu kolejny element (ozn. b)

      3. odłóż na stos wartość b operator a

  3. zdejmij ze stosu wynik

Algorytm konwersji z notacji infiksowej do RPN (w postaci rekurencyjnej)


  • funkcja ONP:

  • Wczytaj znak z wejscia do zmiennej (c)

  • Jeżeli przeczytany znak jest lewym nawiasem

  • Wywołaj funkcję ONP

  • Wczytaj znak z wejscia do zmiennej (a) (to zawsze powinien być operator)

  • Wywołaj funkcję ONP

  • Sciągnij znak z wejścia (to zawsze powinien być prawy nawias) nie zapisując go

  • Wypisz zmienną (a) na wyjscie

  • W przeciwnym wypadku wypisz wczytany znak (c)

Powyższy algorytm działa poprawnie jedynie dla wyrażeń, które mają pełne nawiasowanie (łącznie z nawiasami wokół całego wyrażenia) Uwaga: algorytm nie dziala poprawnie kiedy w wyrażeniu znajduje się unarny minus np.: (-a). Przykładowa gramatyka takich wyrażeń (symbolem startowym jest S):

S -> (S Op S) | Id

Id -> liczby

Op -> + | - | * | /


Algorytm konwersji z notacji infiksowej do RPN


Edsger Dijkstra wymyślił algorytm, nazywany "stacją rozrządową" ponieważ jest w działaniu bardzo podobny do kolejowej stacji rozrządowej. Tak jak algorytm liczący wartość wyrażenia RPN, ten także działa na bazie stosu. Do konwersji używane są 2 zmienne (typu ciągu znakowego) - wejście oraz wyjście. Jest także stos przechowujący operatory nie dodane jeszcze do wyjścia. W uproszczeniu, program czyta po kolei każdą literę i wykonuje operację zależną od tej litery.

Szczegóły algorytmu

  • Póki zostały symbole do przeczytania wykonuj:

Przeczytaj symbol.

  • Jeśli symbol jest liczbą dodaj go do kolejki wyjście.

  • Jeśli symbol jest funkcją włóż go na stos.

  • Jeśli symbol jest znakiem oddzielającym argumenty funkcji (np. przecinek):

  • Dopóki najwyższy element stosu nie jest lewym nawiasem, zdejmij element ze stosu i dodaj go do kolejki wyjście. Jeśli lewy nawias nie został napotkany, to znaczy, że znaki oddzielające zostały postawione w złym miejscu lub nawiasy są źle umieszczone.

  • Jeśli symbol jest operatorem, o1, wtedy:

1) dopóki na górze stosu znajduje się operator, o2 taki, że:

o1 jest łączny lub lewostronnie łączny i jego kolejność wykonywania jest mniejsza lub równa kolejności wyk. o2, lub

o1 jest prawostronnie łączny i jego kolejność wykonywania jest mniejsza od o2,

zdejmij o2 ze stosu i dołóż go do kolejki wyjściowej;

2) włóż o1 na stos operatorów.


  • Jeżeli symbol jest lewym nawiasem to włóż go na stos.

  • Jeżeli symbol jest prawym nawiasem to zdejmuj operatory ze stosu i dokładaj je do kolejki wyjście, dopóki symbol na górze stosu nie jest lewym nawiasem, kiedy dojdziesz do tego miejsca zdejmij lewy nawias ze stosu bez dokładania go do kolejki wyjście. Teraz, jeśli najwyższy element na stosie jest funkcją, także dołóż go do kolejki wyjście. Jeśli stos zostanie opróżniony i nie napotkasz lewego nawiasu, oznacza to, że nawiasy zostały źle umieszczone.

  • Jeśli nie ma więcej symboli do przeczytania, zdejmuj wszystkie symbole ze stosu (jeśli jakieś są) i dodawaj je do kolejki wyścia. (Powinny to być wyłącznie operatory, jeśli natrafisz na jakiś nawias, znaczy to, że nawiasy zostały źle umieszczone.)

Przykład


Wejście 3+4*2/(1-5)^2

Przeczytaj "3"

Dodaj "3" do wyjścia

Wyjście: 3

Przeczytaj "+"

Włóż "+" na stos

Wyjście: 3

Stos: +


Przeczytaj "4"

Dodaj "4" do wyjścia

Wyjście: 3 4

Stos: +


Przeczytaj "*"

Włóż "*" na stos

Wyjście: 3 4

Stos: + *

Przeczytaj "2"

Dodaj "2" do wyjścia

Wyjście: 3 4 2

Stos: + *

Przeczytaj "/"

Zdejmij "*" ze stosu i dodaj do wyjścia, włóż "/" na stos

Wyjście: 3 4 2 *

Stos: + /

Przeczytaj "("

Włóż "(" na stos

Wyjście: 3 4 2 *

Stos: + / (

Przeczytaj "1"

Dodaj "1" do wyjścia

Wyjście: 3 4 2 * 1

Stos: + / (

Przeczytaj "-"

Włóż "-" na stos

Wyjście: 3 4 2 * 1

Stos: + / ( -

Przeczytaj "5"

Dodaj "5" do wyjścia

Wyjście: 3 4 2 * 1 5

Stos: + / ( -

Przeczytaj ")"

Zdejmij "-" ze stosu i dodaj do wyjścia, zdejmij "(" ze stosu

Wyjście: 3 4 2 * 1 5 -

Stos: + /

Przeczytaj "^"

Włóż "^" na stos

Wyjście: 3 4 2 * 1 5 -

Stos: + / ^

Przeczytaj "2"

Dodaj "2" do wyjścia

Wyjście: 3 4 2 * 1 5 - 2

Stos: + / ^

Koniec wyrażenia

Zdejmij stos na wyjście



Wyjście: 3 4 2 * 1 5 - 2 ^ / +








©operacji.org 2019
wyślij wiadomość

    Strona główna