1 wyliczanie i transformacja wyrażeń (wersja skrócona) Opis został przygotowany przez: Bogdana Kreczmera 28 kwietnia 2002 Strona 1 z 68 Zakład Podstaw Cybernetyki i Robotyki
- trochę historii............... - ogólna idea................. 4 do RPN.................... 6 Kalkulator arytmetyczny w RPN............ 12 transformacji do notacji RPN...... algorytmu transformacji notacji 64 Strona 2 z 68
- trochę historii Odwrotna Notacja Polska (RPN - Reverse Polish Notation) opracowana została przez Jana Łukasiewicza (r. 191). Jedna z podstawowych cech tej notacji jest to, że nie wymaga ona stosowania nawiasów. Strona z 68
- trochę historii Odwrotna Notacja Polska (RPN - Reverse Polish Notation) opracowana została przez Jana Łukasiewicza (r. 191). Jedna z podstawowych cech tej notacji jest to, że nie wymaga ona stosowania nawiasów. Pierwszy komputer działajacy w oparciu o notację RPN został zbudowany przez prof. Pawlaka. Niestety nie opatentował on swojego rozwiazania i firma HP skopiowała jego pomysł w swoich kalkulatorach. Strona z 68
- ogólna idea Podstawa własnościa tej notacji jest to, że najpierw zapisuje się argumenty a później operatory, np.: Strona 4 z 68
- ogólna idea Podstawa własnościa tej notacji jest to, że najpierw zapisuje się argumenty a później operatory, np.: To jest normalny zapis: 2 Strona 4 z 68
- ogólna idea Podstawa własnościa tej notacji jest to, że najpierw zapisuje się argumenty a później operatory, np.: To jest normalny zapis: 2 To już jest zapis w RPN: 2 Strona 4 z 68
- ogólna idea Teraz bardziej złożony przykład. Strona z 68
- ogólna idea Teraz bardziej złożony przykład. Wyrażenie w normalnej notacji: (2 ) ( 1) - 7 Strona z 68
- ogólna idea Teraz bardziej złożony przykład. Wyrażenie w normalnej notacji: (2 ) ( 1) - 7 W notacji RPN: 2 1 7 - Strona z 68
do RPN Zobaczmy teraz jak wyrażenie w notacji zwyczajowej możemy przekształcić do notacji RPN. Strona 6 z 68
do RPN Zobaczmy teraz jak wyrażenie w notacji zwyczajowej możemy przekształcić do notacji RPN. W tym celu prześledźmy jak przekształcać należy poniższe wyrażenie. (2 ) ( 1) - 7 Strona 6 z 68
do RPN Zobaczmy teraz jak wyrażenie w notacji zwyczajowej możemy przekształcić do notacji RPN. W tym celu prześledźmy jak przekształcać należy poniższe wyrażenie. (2 ) ( 1) - 7 W pierwszym kroku szukamy podwyrażeń, które wykonaja się przed innymi. Strona 6 z 68
do RPN (2 ) ( 1) - 7 Oto i one. Sprowadzamy je do zapisu RPN poprzez przestawienie operatora. Strona 7 z 68
do RPN 2 1-7 Wykonujemy tę operację dla każdego z nich z osobna. Ramki wokół wyrażeń zostały użyte, aby oddzielić to co jest już zapisane w notacji RPN od pozostałej części. Strona 8 z 68
do RPN 2 1-7 Następnym działaniem, które się wykona, jest mnożenie. Wyrażenia w ramkach traktujemy jak liczby. Całość przekształcamy w identyczny sposób jak poprzednio przestawiajac operator. Strona 9 z 68
do RPN 2 1-7 Ponownie traktujac wyrażenie w ramce jako jedna liczbę dokonujemy ostatniej transformacji dla ostatniego działania. Strona 10 z 68
do RPN 2 1 7 - W ten sposób dochodzimy do finalnej postaci wyrażenia zapisanego w notacji RPN. Strona 11 z 68
Kalkulator arytmetyczny w RPN Istotna zaleta odwrotnej notacji polskiej jest to, że istnieje dla niej prosty algorytm wyliczenia wyrażenia przedstawionego w tej notacji. Strona 12 z 68
Kalkulator arytmetyczny w RPN Istotna zaleta odwrotnej notacji polskiej jest to, że istnieje dla niej prosty algorytm wyliczenia wyrażenia przedstawionego w tej notacji. ten bazuje na pojęciu prostej struktury zwanej stosem, która jest kolejka typu LIFO (ang. Last In First Out - ostatni wchodzi pierwszy wychodzi). Strona 1 z 68
Kalkulator arytmetyczny w RPN Istotna zaleta odwrotnej notacji polskiej jest to, że istnieje dla niej prosty algorytm wyliczenia wyrażenia przedstawionego w tej notacji. ten bazuje na pojęciu prostej struktury zwanej stosem, która jest kolejka typu LIFO (ang. Last In First Out - ostatni wchodzi pierwszy wychodzi). Idea tego algorytmu zostanie wyjaśniona na przykładzie, który wcześniej rozważaliśmy, a mianowicie: (2 ) ( 1) - 7 Strona 1 z 68
Kalkulator arytmetyczny w RPN Istotna zaleta odwrotnej notacji polskiej jest to, że istnieje dla niej prosty algorytm wyliczenia wyrażenia przedstawionego w tej notacji. ten bazuje na pojęciu prostej struktury zwanej stosem, która jest kolejka typu LIFO (ang. Last In First Out - ostatni wchodzi pierwszy wychodzi). Idea tego algorytmu zostanie wyjaśniona na przykładzie, który wcześniej rozważaliśmy, a mianowicie: (2 ) ( 1) - 7 W notacji RPN: 2 1 7 - Strona 1 z 68
Kalkulator arytmetyczny w RPN Wejście: 2 1 7 - Stos: = Przykład, który dalej będzie przedstawiany, zorganizowany jest w następujacy sposób: Strona 14 z 68 Obliczenia dla wyrażenia: (2 ) ( 1) 7
Kalkulator arytmetyczny w RPN Wejście: 2 1 7 - Stos: Na wejściu mamy wyrażenie w notacji RPN. Odpowiada jemu przedstawione na dole wyrażenie w notacji zwyczajowej. Ponadto mamy obszar roboczy, w którym wykonywane będa poszczególne działania oraz stos, w którym składowane będa wczytywane liczby. = Strona 1 z 68 Obliczenia dla wyrażenia: (2 ) ( 1) 7
Kalkulator arytmetyczny w RPN Wejście: 2 1 7 - Stos: = Czytany jest pierwszy element wyrażenia. Strona 16 z 68 Obliczenia dla wyrażenia: (2 ) ( 1) 7
Kalkulator arytmetyczny w RPN Wejście: 2 1 7 - Stos: 2 = Ze względu na to, że jest to liczba, to umieszczamy ja na stosie. Strona 17 z 68 Obliczenia dla wyrażenia: (2 ) ( 1) 7
Kalkulator arytmetyczny w RPN Wejście: 2 1 7 - Stos: 2 = Czytana jest druga liczba i tak jak poprzednio umieszczona zostaje na stosie. Strona 18 z 68 Obliczenia dla wyrażenia: (2 ) ( 1) 7
Kalkulator arytmetyczny w RPN Wejście: 2 1 7 - = Stos: 2 Wczytujac operator rozpoczynamy proces interpretacji napotkanej operacji arytmetycznej i jej wykonanie. Strona 19 z 68 Obliczenia dla wyrażenia: (2 ) ( 1) 7
Kalkulator arytmetyczny w RPN Wejście: 2 1 7 - Stos: 2 = W tym celu pobieramy z wierzchołka stosu liczbę i traktujemy ja jako drugi argument danej operacji arytmetycznej. Strona 20 z 68 Obliczenia dla wyrażenia: (2 ) ( 1) 7
Kalkulator arytmetyczny w RPN Wejście: 2 1 7 - Stos: 2 = Powtarzamy ta czynność pobierajac kolejna liczbę z wierzchołka stosu i traktujemy ja tym razem jako pierwszy argument danej operacji arytmetycznej. Strona 21 z 68 Obliczenia dla wyrażenia: (2 ) ( 1) 7
Kalkulator arytmetyczny w RPN Wejście: 2 1 7 - Stos: 7 2 = 7 Wykonujemy zadana operację arytmetyczna i jej wynik umieszczamy na stosie. Strona 22 z 68 Obliczenia dla wyrażenia: (2 ) ( 1) 7
Kalkulator arytmetyczny w RPN Wejście: 2 1 7 - Stos: 7 = Po wczytaniu kolejnej liczby umieszczamy ja na stosie, tak jak to robiliśmy wcześniej. Strona 2 z 68 Obliczenia dla wyrażenia: (2 ) ( 1) 7
Kalkulator arytmetyczny w RPN Wejście: 2 1 7 - Stos: 1 7 = To samo czynimy z następna wczytana liczba. Strona 24 z 68 Obliczenia dla wyrażenia: (2 ) ( 1) 7
Kalkulator arytmetyczny w RPN Wejście: 2 1 7 - Stos: 1 7 = Wczytanie operatora powoduje przejście do procesu interpretacji i wykonania działania. Strona 2 z 68 Obliczenia dla wyrażenia: (2 ) ( 1) 7
Kalkulator arytmetyczny w RPN Wejście: 2 1 7 - Stos: 7 1 = W tym celu z wierzchołka stosu pobieramy kolejno jego dwa argumenty... Strona 26 z 68 Obliczenia dla wyrażenia: (2 ) ( 1) 7
Kalkulator arytmetyczny w RPN Wejście: 2 1 7 - Stos: 4 7 1 = 4... i wykonujemy działanie składujac jego wynik na stosie. Strona 27 z 68 Obliczenia dla wyrażenia: (2 ) ( 1) 7
Kalkulator arytmetyczny w RPN Wejście: 2 1 7 - Stos: 7 4 = Wczytanie następnego operatora powoduje tak jak wcześniej ściagnięcie jego dwóch argumentów ze stosu. Strona 28 z 68 Obliczenia dla wyrażenia: (2 ) ( 1) 7
Kalkulator arytmetyczny w RPN Wejście: 2 1 7 - Stos: 28 7 4 = 28 Po wykonaniu zadanej operacji jej wynik umieszczamy na stosie. Strona 29 z 68 Obliczenia dla wyrażenia: (2 ) ( 1) 7
Kalkulator arytmetyczny w RPN Wejście: 2 1 7 - Stos: 7 28 = Po wczytaniu kolejnej liczby umieszczamy ja na stosie. Strona 0 z 68 Obliczenia dla wyrażenia: (2 ) ( 1) 7
Kalkulator arytmetyczny w RPN Wejście: 2 1 7 - Stos: 28-7 = Wczytujac kolejny operator powtarzamy wcześniejsza procedurę i ściagamy dwa kolejne argumenty ze stosu. Strona 1 z 68 Obliczenia dla wyrażenia: (2 ) ( 1) 7
Kalkulator arytmetyczny w RPN Wejście: 2 1 7 - Stos: 21 28-7 = 21 Jej wynik umieszczamy na stosie, co kończy realizację całego algorytmu. Warto zauważyć, że dla poprawnie zbudowanego wyrażenia po zakończeniu jego interpretacji na szczycie stosu pozostanie tylko jedna liczba (przy założeniu, że startujemy z pustym stosem). Strona 2 z 68 Obliczenia dla wyrażenia: (2 ) ( 1) 7
transformacji do notacji RPN Idea konstrukcji algorytmu zostanie zademonstrowana na przykładzie, który był już wcześniej omawiany (aby zobaczyć przejdź tutaj). Sam algorytm realizuje de facto proces transformacji, który intuicyjnie jest przedstawiony w części, do której odsyłacz znajduje się w poprzednim zdaniu. Tak więc jeszcze raz zajmiemy się wyrażeniem: (2 ) ( 1) 7 Strona z 68
transformacji do notacji RPN Idea konstrukcji algorytmu zostanie zademonstrowana na przykładzie, który był już wcześniej omawiany (aby zobaczyć przejdź tutaj). Sam algorytm realizuje de facto proces transformacji, który intuicyjnie jest przedstawiony w części, do której odsyłacz znajduje się w poprzednim zdaniu. Tak więc jeszcze raz zajmiemy się wyrażeniem: (2 ) ( 1) 7 Omawiany algorytm jest słuszny dla operatorów /. Opis uogólnienia tego algorytmu na pozostałe operatory dwuargumentowe znajduje się w następnej części. Strona z 68
transformacji do notacji RPN Wejście: ( 2 ) ( 1 ) 7 Wartości priorytetów / liczby 0 1 2 N I L Niniejszy przykład zorganizowany jest następujaco: Z wejścia wczytywane jest wyrażenie arytmetyczne. Pobieranym elementom (operatorom i liczbom) nadawane będa priorytety wg. tabeli powyżej, a następnie będa składowane w kolejce jednokierunkowej. Strona 4 z 68
transformacji do notacji RPN Wejście: ( Wartości priorytetów 2 ) ( 1 ) 7 / liczby 0 1 2 N I L Prześledźmy więc teraz jak działa algorytm. Na wejściu wczytany zostaje pierwszy element wyrażenia arytmetycznego. Jest nim nawias otwierajacy. Strona z 68
transformacji do notacji RPN Wejście: ( Wartości priorytetów 2 ) ( 1 ) 7 / liczby 4 N I L Pojawienie się nawiasu otwierajacego powoduje zwiększenie wszystkich nadawanych priorytetów o wartość. Strona 6 z 68
transformacji do notacji RPN Wejście: ( 2 Wartości priorytetów 2 ) ( 1 ) 7 / liczby 4 Jako następny element wyrażenia wczytana zostaje liczba. Umieszczamy ja w kolejce nadajac jej priorytet (dolna wartość w ramce) zgodny z tabela nadawanych priorytetów. Strona 7 z 68
transformacji do notacji RPN Wejście: ( 2 Wartości priorytetów 2 / liczby 4 ) ( 1 ) 7 Czytany jest kolejny element wyrażenia. Traktujemy go podobnie jak wcześniej wczytana liczbę i umieszczamy go na końcu kolejki. Strona 8 z 68
transformacji do notacji RPN Wejście: ( 2 Wartości priorytetów 2 / liczby 4 ) ( 1 ) 7 Wczytana zostaje następna liczba i postępujemy podobnie jak poprzednio umieszczajac ja na końcu listy. Strona 9 z 68
transformacji do notacji RPN Wejście: ( 2 ) Wartości priorytetów 2 / liczby 4 Dochodzimy do nawiasu zamykajacego. ( 1 ) 7 Strona 40 z 68
transformacji do notacji RPN Wejście: ( 2 ) Wartości priorytetów 2 / liczby 0 1 2 ( 1 ) 7 Wykrycie nawiasu zamykaj acego powoduje obniżenie wartości nadawanych priorytetów o. Strona 41 z 68
transformacji do notacji RPN Wejście: ( 2 ) Wartości priorytetów 2 / liczby 0 1 2 1 ( 1 ) 7 Wczytujemy kolejny element i tak jak wcześniej umieszczamy go na końcu listy z odpowiednia wartościa priorytetu. Strona 42 z 68
transformacji do notacji RPN Wejście: ( 2 ) ( Wartości priorytetów 2 / liczby 4 1 1 ) 7 Dochodzimy do nawiasu otwieraj acego. Powoduje to ponownie zwiększenie nadawanych priorytetów o. Strona 4 z 68
transformacji do notacji RPN Wejście: ( 2 ) ( Wartości priorytetów 2 / liczby 4 1 1 ) 7 Wczytywana zostaje liczba i wg. stosowanej już procedury dodana zostaje na koniec listy z odpowiadajacym jej priorytetem. Strona 44 z 68
transformacji do notacji RPN Wejście: ( 2 ) ( Wartości priorytetów 2 / liczby 4 1 Podobnie postępujemy z następnym operatorem... 1 ) 7 Strona 4 z 68
transformacji do notacji RPN Wejście: ( 2 ) ( 1 Wartości priorytetów 2 / liczby 4... oraz z następna liczba. 1 1 ) 7 Strona 46 z 68
transformacji do notacji RPN Wejście: ( 2 ) ( 1 ) Wartości priorytetów 2 / liczby 0 1 2 1 1 7 Strona 47 z 68 Wczytanie nawiasu zamykaj acego powoduje obniżenia wartości nadawanych priorytetów o.
transformacji do notacji RPN Wejście: ( 2 ) ( 1 ) 7 Wartości priorytetów 2 / liczby 0 1 2 1 W analogiczny sposób jak wcześniej wczytujemy dwa kolejne elementy i umieszczamy je na końcu kolejki. 1 0 7 Strona 48 z 68
transformacji do notacji RPN Wejście: ( 2 ) ( 1 ) 7 Wartości priorytetów 2 / liczby 0 1 2 1 Teraz zaczynamy drugi etap realizacji algorytmu, który ma nas doprowadzić do właściwego zapisu wyrażenia w notacji RPN. 1 0 7 Strona 49 z 68
transformacji do notacji RPN Wejście: ( 2 ) ( 1 ) 7 Wartości priorytetów 2 / liczby 0 1 2 1 W tym celu szukamy na liście pierwszego operatora (od poczatku listy), który ma największy priorytet. Jest nim operator z priorytetem. 1 0 7 Strona 0 z 68
transformacji do notacji RPN Wejście: ( 2 ) ( 1 ) 7 Wartości priorytetów 2 / liczby 0 1 2 1 Następnie sprawdzamy, czy następny element listy ma priorytet większy. Jeśli tak jest, to... 1 0 7 Strona 1 z 68
transformacji do notacji RPN Wejście: ( 2 ) ( 1 ) 7 Wartości priorytetów 2 / liczby 0 1 2 1... zamieniamy je miejscami. 1 0 7 Strona 2 z 68
transformacji do notacji RPN Wejście: ( 2 ) ( 1 ) 7 Wartości priorytetów 2 / liczby 0 1 2 1 Proces przestawiania kontynuujemy, aż do momentu gdy sasiedni element ma priorytet mniejszy lub równy, tak jak to ma miejsce w naszym przypadku. 1 0 7 Strona z 68
transformacji do notacji RPN Wejście: ( 2 ) ( 1 ) 7 Wartości priorytetów 2 / liczby 0 1 2 1 Teraz operatorowi dla którego znaleźliśmy już właściwe miejsce nadajemy nowa wartość priorytetu, która jest maksymalna wartościa na liście. W naszym przypadku jest to wartość. 1 0 7 Strona 4 z 68
transformacji do notacji RPN Wejście: ( 2 ) ( 1 ) 7 Wartości priorytetów 2 / liczby 0 1 2 1 Ponownie szukamy na liście pierwszego operatora o największym priorytecie, lecz o wartości mniejszej niż wartość maksymalna (w naszym przypadku ). Jest nim kolejny operator dodawania. 1 0 7 Strona z 68
transformacji do notacji RPN Wejście: ( 2 ) ( 1 ) 7 Wartości priorytetów 2 / liczby 0 1 2 1 Ponownie zaczynamy przesuwać ten element na koniec listy, aż do momentu gdy jego kolejny sasiad ma priorytet mniejszy lub równy. Gdy taki przypadek już zachodzi, zmieniamy... 1 0 7 Strona 6 z 68
transformacji do notacji RPN Wejście: ( 2 ) ( 1 ) 7 Wartości priorytetów 2 / liczby 0 1 2 1 1... jego priorytet na wartość maksymalna. 0 7 Strona 7 z 68
transformacji do notacji RPN Wejście: ( 2 ) ( 1 ) 7 Wartości priorytetów 2 / liczby 0 1 2 1 Ponownie szukamy pierwszego operatora na liście o największym priorytecie i zarazem mniejszym od wartości maksymalnej. Tym razem jest nim operator mnożenia. 1 0 7 Strona 8 z 68
transformacji do notacji RPN Wejście: ( 2 ) ( 1 ) 7 Wartości priorytetów 2 / liczby 0 1 2 Zgodnie ta sama procedura jak wcześniej przestawiamy go, aż do momentu, gdy jego sasiad ma priorytet mniejszy lub równy. 1 1 0 7 Strona 9 z 68
transformacji do notacji RPN Wejście: ( 2 ) ( 1 ) 7 Wartości priorytetów 2 / liczby 0 1 2 Nadajemy wówczas rozważanemu operatorowi priorytet maksymalny. 1 0 7 Strona 60 z 68
transformacji do notacji RPN Wejście: ( 2 ) ( 1 ) 7 Wartości priorytetów 2 / liczby 0 1 2 Ponownie szukamy pierwszego operatora, który ma największy priorytet spośród tych, których priorytety nie maja wartości maksymalnej. Tym razem jest to operator odejmowania. 1 0 7 Strona 61 z 68
transformacji do notacji RPN Wejście: ( 2 ) ( 1 ) 7 Wartości priorytetów 2 / liczby 0 1 2 Zgodnie z już przedstawiona procedura dokonujemy zamiany i nadajemy mu priorytet maksymalny. 1 7 Strona 62 z 68
transformacji do notacji RPN Wejście: ( 2 ) ( 1 ) 7 Wartości priorytetów 2 / liczby 0 1 2 W ten sposób wszystkie operatory maja już priorytety maksymalne, co jest warunkiem stopu algorytmu. Teraz, aby otrzymać wyrażenie w notacji RPN wystarczy wypisać kolejne elementy listy poczynajac od jej poczatku. 1 7 Strona 6 z 68
algorytmu transformacji notacji Operatory dwuargumentowe możemy podzielić na trzy grupy, a mianowicie: Strona 64 z 68
algorytmu transformacji notacji Operatory dwuargumentowe możemy podzielić na trzy grupy, a mianowicie: operatory lewostronnie łaczne, np. operator odejmowania (również dzielenia), tzn.: a b c = (a b) c Strona 64 z 68
algorytmu transformacji notacji Operatory dwuargumentowe możemy podzielić na trzy grupy, a mianowicie: operatory lewostronnie łaczne, np. operator odejmowania (również dzielenia), tzn.: a b c = (a b) c operatory prawostronnie łaczne, np. operator potęgowania, który w zwyczajowej notacji nie jest reprezentowany przez żaden znak, a jedynie przez formę zapisu. Tak więc: a bc = a (bc ) Strona 64 z 68
algorytmu transformacji notacji Operatory dwuargumentowe możemy podzielić na trzy grupy, a mianowicie: operatory lewostronnie łaczne, np. operator odejmowania (również dzielenia), tzn.: a b c = (a b) c operatory prawostronnie łaczne, np. operator potęgowania, który w zwyczajowej notacji nie jest reprezentowany przez żaden znak, a jedynie przez formę zapisu. Tak więc: a bc = a (bc ) operatory obustronnie łaczne, np. operatory dodawania i mnożenia, tzn.: a b c = (a b) c = a (b c) Strona 64 z 68
algorytmu transformacji notacji Aby uwzględnić te wszystkie przypadki trzeba rozszerzyć warunki realizacji dwóch operacji, a mianowicie: Strona 6 z 68
algorytmu transformacji notacji Aby uwzględnić te wszystkie przypadki trzeba rozszerzyć warunki realizacji dwóch operacji, a mianowicie: warunek szukania kolejnego operatora, warunek przestawiania elementu w kolejce. Strona 6 z 68
algorytmu transformacji notacji W przypadku szukania kolejnego operatora w kolejce wczytanych elementów, dla operatora prawołacznego należy szukać ostatniego elementu (a nie pierwszego), który ma największy priorytet i jednocześnie mniejszy od wartości maksymalnej. Różnica w sformułowaniu w stosunku do warunku, który był wykorzystywany w omawianym przykładzie zaczyna być istotna w momencie, gdy pojawia się operatory o jednakowej wartości priorytetu. Strona 66 z 68
algorytmu transformacji notacji Warunek przestawienia elementów w kolejce powinien mieć w uogólnionej wersji postać: Strona 67 z 68
algorytmu transformacji notacji Warunek przestawienia elementów w kolejce powinien mieć w uogólnionej wersji postać: Jeżeli rozważany operator jest operatorem lewostronnie lub obustronnie łacznym, to elementy zamieniamy miejscami jeśli jego sasiad ma priorytet większy. Jeżeli natomiast operator jest prawostronnie łacznym, to elementy zamieniamy miejscami jeśli jego sasiad ma priorytet większy lub równy. Strona 67 z 68
Wszelkie uwagi i spostrzeżenia do niniejszej prezentacji sa mile widziane. Proszę je kierować na adres kreczmer@diablo.ict.pwr.wroc.pl Strona 68 z 68