Podstawowe struktury dynamiczne

Transkrypt

Podstawowe struktury dynamiczne
2009-11-03
Podstawowe struktury dynamiczne
Algorytmy i struktury danych
Wykład 3.
Rok akademicki: 2009/2010
Struktura dynamiczna
• Struktura dynamiczna – struktura, która:
– tworzona jest w programie poprzez jawne użycie odpowiedniej
instrukcji (np. operatora new),
– może zmieniad swoją wielkośd – liczbę elementów składowych (zmiana
ilości zajmowanej pamięci operacyjnej),
– jej likwidacja prowadzi do odzyskania zajmowanej przez nią pamięci.
2
1
2009-11-03
Struktury dynamiczne w języku Java
•
•
•
•
•
•
•
kolekcja (Collection) - grupa obiektów (obiekty mogą się powtarzad),
zbiór (Set) - grupa elementów (obiekty nie mogą się powtarzad),
zbior posortowany (SortedSet) - jak zbiór, ale kolejnośd elementów jest
określona, możliwe jest pobranie następnego lub poprzedniego elementu
zbioru (np. uporządkowany alfabetycznie zbiór liter lub zbiór łaocuchów),
lista (List) - kolekcja, w której elementy mogą się powtarzad, elementy listy
są uporządkowane; dostęp do nich jest również możliwy poprzez indeks.
Rodzaje struktur listowych: stos, kolejka, lista jednokierunkowa, lista
dwukierunkowa, lista cykliczna,
tablica asocjacyjna (Map) – zbiór par (klucz, wartośd), dostęp do elementu
jest możliwy po podaniu klucza,
posortowana tablica asocjacyjna (SortedMap) - tablica asocjacyjna
zawierająca elementy uporządkowane według klucza.
drzewa i grafy  kolejne wykłady!!!
3
Definicja struktur dynamicznych w postaci interfejsów
4
2
2009-11-03
Interfejs Collection
5
Interfejs Iterator
public interface Iterator {
boolean hasNext();
Object next();
void remove();
}
6
3
2009-11-03
Wykorzystanie iteratora do usuwania elementów
Collection collection = ...;
Iterator iterator = collection.iterator();
while (iterator.hasNext()) {
Object element = iterator.next();
if (removalCheck(element)) {
iterator.remove();
}
}
7
Klasa AbstractCollection
• public abstract class AbstractCollection extends Object
implements Collection
• przy tworzeniu kolekcji niezbędne jest:
–
–
–
–
określenie sposobu przechowywania danych
zdefiniowanie metody iterator()
zdefiniowanie metody size()
zdefiniowanie metody add() - dostępna metoda add() generuje
wyjątek UnsupportedOperationException
– zdefiniowanie konstruktorów: Kolekcja() oraz Kolekcja(Collection
c)
8
4
2009-11-03
Kolekcja – przykład 1/6
import java.util.Collection;
import java.util.AbstractCollection;
import java.util.Iterator;
import java.util.NoSuchElementException;
class KolekcjaLiterA extends AbstractCollection implements Iterator
{
private int ileLiter;
private int aktualnaLitera;
private boolean czyMoznaUsunac;
KolekcjaLiterA()
{
ileLiter = 0;
czyMoznaUsunac = false;
aktualnaLitera = 0;
}
9
Kolekcja – przykład 2/6
KolekcjaLiterA(Collection c) {
addAll(c);
}
public Iterator iterator() {
aktualnaLitera = 0;
return this;
}
public boolean hasNext() {
return (aktualnaLitera < ileLiter);
}
10
5
2009-11-03
Kolekcja – przykład 3/6
public Object next() {
if (aktualnaLitera < ileLiter) {
aktualnaLitera++;
czyMoznaUsunac = true;
return new Character('A');
}
else
{
czyMoznaUsunac = false;
throw new NoSuchElementException("Brak
nastepnego elementu");
}
}
11
Kolekcja – przykład 4/6
public void remove() {
if (czyMoznaUsunac) {
ileLiter--;
czyMoznaUsunac = false;
}
}
public int size() {
return ileLiter;
}
public boolean add(Object o)
{
if(o == null)
throw new NullPointerException("Pusty wskaznik");
if(!(o instanceof Character))
throw new ClassCastException("Tylko obiekty typu Character");
Character znak = (Character) o;
if (znak.charValue() != 'A')
throw new IllegalArgumentException("Tylko A");
ileLiter++;
return true;
}
12
6
2009-11-03
Kolekcja – przykład 5/6
public String toString()
{
StringBuffer buf = new StringBuffer();
for (int i = 0; i < size(); i++)
buf.append('A');
return buf.toString();
}
}
13
Kolekcja – przykład 6/6
public class TestKolekcjiLiterA {
public static void main(String [] args) {
KolekcjaLiterA pierwsza = new KolekcjaLiterA();
pierwsza.add(new Character('A'));
pierwsza.add(new Character('A'));
System.out.println("Pierwsza kolekcja: " + pierwsza);
KolekcjaLiterA druga= new KolekcjaLiterA();
druga.add(new Character('A'));
druga.add(new Character('A'));
druga.add(new Character('A'));
druga.add(new Character('A'));
System.out.println("Druga kolekcja: " + druga);
druga.removeAll(pierwsza);
System.out.println("Druga kolekcja: " + druga);
druga.add(new Character('A'));
System.out.println("Druga kolekcja: " + druga);
KolekcjaLiterA trzecia = new KolekcjaLiterA(druga);
System.out.println("Trzecia kolekcja: " + trzecia);
}
}
14
7
2009-11-03
Interfejs Set
15
Elementy w zbiorze nie mogą się powtarzad!
• Do sprawdzenia, czy dany element występuje w zbiorze służy
zdefiniowana w klasie Object metoda:
public boolean equals(Object obj)
• implementacja zawarta w klasie Object sprawdza, czy
referencja do bieżącego obiektu jest równa referencji do
obiektu reprezentowanego przez parametr (czyli, czy te dwa
obiektu zajmują to samo miejsce w pamięci) – dla klas
definiowanych przez programistę zwykle konieczne jest
zredefiniowanie metody equals.
16
8
2009-11-03
Klasa AbstractSet
• public abstract class AbstractSet extends AbstractCollection
implements Set
• Klasa AbstractSet jest wykorzystywana w podobny sposób jak
klasa AbstractCollection.
17
Klasa HashSet - implementacja zbioru
import java.util.*;
public class PrzykladZbioru {
public static void main(String args[]) {
Set set = new HashSet();
set.add("Wiosna");
set.add("Lato");
set.add("Jesien");
set.add("Zima");
set.add("Zima");
set.add("Zima");
set.add("Zima");
System.out.println(set);
Wynik działania programu:
[Jesien, Wiosna, Zima, Lato]
[Jesien, Wiosna, Zima]
set.remove("Lato");
System.out.println(set);
}
}
18
9
2009-11-03
Implementacja zbiorów typu HashSet
• Do przechowywania elementów zbioru typu HashSet
wykorzystywana jest struktura danych nazywana tablicą z
haszowaniem.
• Podstawowe cechy tablicy z haszowaniem:
– pozwala na szybki dostęp do jej elementów składowych,
– pozwala na efektywne zarządzanie pamięcią operacyjną.
– W tablicy z haszowaniem mogą byd przechowywane obiekty, dla
których można wyznaczyd wartośd klucza.
19
Cechy klucza haszującego (skrótu)
•
•
•
•
•
klucz jest liczbą całkowitą,
wartośd klucza jest uzależniona od wartości przechowywanych w obiekcie;
dwa identyczne obiekty (ze względu na metodę equals – czyli tego samego
typu i przechowujące takie same wartości) mają identyczne wartości
kluczy;
dwa różne obiekty mogą posiadad identyczne lub różne wartości kluczy
(zaleca się, aby były one różne)
w języku Java do wyznaczenia wartości klucza służy funkcja z klasy Object:
public int hashCode()
•
funkcja hashCode jest dziedziczona przez wszystkie inne klasy (może byd
redefiniowana)
20
10
2009-11-03
Funkcja hashCode() dla klasy String
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
class Test {
public static void main(String [] args) {
String s = "Java";
System.out.println(s.hashCode());
}
}
Efekt działania:
2301506
21
Funkcja hashCode() w klasie Object
• funkcja hashCode() zdefiniowana w klasie Object zwraca
informację o położeniu obiektu (adres obiektu przekształcony
do wartości typu int) – zwykle dla klas definiowanych przez
programistę konieczna jest redefinicja, gdyż nie jest spełniony
warunek głoszący, że równe obiekty (equals) posiadają
identyczne kody
• jeśli obiekty mają byd przechowywane w zbiorze typu HashSet
to muszą mied poprawnie zdefiniowaną funkcję hashCode().
22
11
2009-11-03
Struktura tablicy z haszowaniem
funkcja haszująca: hashCode() % n
gdzie: n – liczba elementów w wektorze
23
Przykład 1/4
import java.util.*;
class Lancuch
{
String s;
Lancuch(String s)
{
this.s = s;
}
public String toString()
{
return s;
}
}
24
12
2009-11-03
Przykład 2/4
public class Test
{
public static void main(String args[])
{
Set set = new HashSet();
set.add(new Lancuch("Szczecin"));
set.add(new Lancuch("Olsztyn"));
set.add(new Lancuch("Opole"));
set.add(new Lancuch("Katowice"));
set.add(new Lancuch("Katowice"));
System.out.println(set);
}
}
25
Przykład 3/4
Efekt działania programu:
[Olsztyn, Szczecin, Katowice, Opole, Katowice]
WYNIK JEST BŁĘDNY – W ZBIORZE WYSTĘPUJĄ DWA
IDENTYCZNE ELEMENTY!!!
Konieczna jest modyfikacja klasy Lancuch
26
13
2009-11-03
Przykład 4/4
class Lancuch {
String s;
Lancuch(String s) {
this.s = s;
}
public String toString() {
return s;
}
public boolean equals(Object obj) {
if (!(obj instanceof Lancuch))
return false;
if (((Lancuch) obj).s.equals(s))
return true;
else
return false;
}
public int hashCode() {
return s.hashCode();
}
}
Efekt działania programu:
[Szczecin, Katowice, Opole, Olsztyn]
27
Interfejs SortedSet
Interfejs SortedSet implementowany jest przez klasę TreeSet.
28
14
2009-11-03
Interfejs Comparable
Operację porządkowania elementów definiuje interfejs Comparable
Porównuje dany obiekt z obiektem reprezentowanym przez parametr
i zwraca:
• wartośd ujemną, jeśli dany obiekt jest mniejszy,
• zero, jeśli są równe,
• wartośd dodatnią, jeśli dany obiekt jest większy.
Jeśli elementami zbioru typu TreeSet są obiekty implementujące interfejs
Comparable, to są one porządkowane zgodnie ze sposobem działania
metody compareTo().
29
Przykład 1/2
import java.util.*;
public class PrzykladZbioru
{
public static void main(String args[])
{
Set set = new TreeSet();
set.add("Wiosna");
set.add("Lato");
set.add("Jesien");
set.add("Zima");
30
15
2009-11-03
Przykład 2/2
System.out.println(set);
set.remove("Lato");
System.out.println(set);
}
}
Efekt działania programu:
[Jesien, Lato, Wiosna, Zima]
31
Interfejs Comparator
Jeśli elementami zbioru mają byd obiekty, które nie implementują
interfejsu Comparable, to sposób ich porównania dokonywany jest za
pomocą metod interfejsu Comparator.
Utworzony obiekt pozwalający na porównanie elementów zbioru
(komparator) jest przekazywany jako parametr konstruktora
obiektu TreeSet.
32
16
2009-11-03
Przykład 1/2
import java.util.*;
class PorownajDlugosciTekstow implements Comparator
{
public int compare(Object element1, Object element2)
{
int dlugosc1 = ((String) element1).length();
int dlugosc2 = ((String) element2).length();
return dlugosc1 - dlugosc2;
}
}
33
Przykład 2/2
public class Porownania {
public static void main(String [] args)
{
PorownajDlugosciTekstow p = new PorownajDlugosciTekstow();
TreeSet zbior = new TreeSet(p);
zbior.add("Andrzej");
zbior.add("Basia");
zbior.add("Jan");
zbior.add("Boleslaw");
System.out.println(zbior);
}
}
Wynik działania programu:
[Jan, Basia, Andrzej, Boleslaw]
34
17
2009-11-03
Implementacja zbioru typu TreeSet
10
5
14
7
12
18
15
Zbiory typu TreeSet przechowywane są w postaci
drzewa poszukiwao binarnych - Dla każdego węzła, wszystkie
elementy jego lewego poddrzewa (jeżeli takie istnieją)
reprezentują elementy mniejsze od elementu reprezentowanego
przez ten węzeł, zaś wszystkie elementy jego prawego poddrzewa
(jeżeli takie istnieją) reprezentują elementy większe od elementu
reprezentowanego przez rozpatrywany węzeł.
35
Reprezentacja struktur listowych
36
18
2009-11-03
Listy
• kolekcja uporządkowanych elementów (z możliwością
powtórzeo);
• elementy listy są ponumerowane (od zera);
• podstawowe cechy listy opisane są w interfejsie List.
37
Interfejs List
38
19
2009-11-03
Interfejs ListIterator
39
Implementacja list w języku Java
• ArrayList - implementacja interfejsu List jako wektora o
zmieniających się wymiarach
• LinkedList - implementacja interfejsu List jako struktury
listowej.
40
20
2009-11-03
Klasa ArrayList
• Elementy listy przechowywane są wektorze
• w przypadku braku miejsca w wektorze tworzony jest
nowy wektor o wielkości:
nnowy = 1,5 * nstary + 1
do którego kopiowane są elementy z dotychcza-sowego
wektora; po przekopiowaniu dotychczasowy wektor jest
usuwany z pamięci.
41
Zastosowania klasy ArrayList
• stosowanie list typu ArrayList jest zalecane wtedy, gdy:
– często zachodzi potrzeba odwoływania się do elementów listy,
– rzadko zachodzi potrzeba modyfikacji wielkości listy.
42
21
2009-11-03
ArrayList – przykładowy program
import java.util.*;
public class Wektor {
public static void main(String[] args) {
ArrayList w = new ArrayList(5);
for (int i = 1; i <= 10; i++)
w.add(new Integer(i));
//wyswietlenie wektora
System.out.println("Wektor: " + w);
43
ArrayList – przykładowy program
//korzystanie z ListIteratora
ListIterator iter = w.listIterator(0);
while (iter.hasNext())
if (((Integer) iter.next()).intValue() % 2 != 0)
iter.remove();
//wyswietlenie wektora
System.out.println("Wektor: " + w);
}
}
44
22
2009-11-03
Klasa LinkedList
 lista typu LinkedList przechowywana jest jako lista
dwukierunkowa,
45
Zastosowanie klasy LinkedList
• stosowanie listy typu LinkedList jest zalecane wtedy, gdy:
– rzadko zachodzi potrzeba odwoływania się do elementów listy za
pomocą indeksów,
– często zachodzi potrzeba dodawania i usuwania elementów
znajdujących się na liście.
46
23
2009-11-03
Klasa LinkedList – przykład 1/3
import java.util.*;
public class LiczbyPierwsze {
static boolean czyPierwsza(int liczba)
{
for (int i = 2; i <= Math.min(
(int) Math.sqrt(liczba) + 1,liczba-1); i++)
if (liczba % i == 0)
return false;
return true;
}
47
Klasa LinkedList – przykład 2/3
public static void main(String[] args) {
LinkedList lista = new LinkedList();
for (int i = 1; i <= 20; i++)
lista.add(new Integer(i));
System.out.println("Lista: " + lista);
ListIterator iter = lista.listIterator();
Integer element;
while (iter.hasNext())
if (czyPierwsza((element = (Integer) iter.next()).intValue()))
iter.set("{" + element.intValue() + "}");
System.out.println("Lista: " + lista);
iter = lista.listIterator();
while (iter.hasNext())
if (!(iter.next() instanceof String))
iter.remove();
System.out.println("Lista: " + lista);
}
}
48
24
2009-11-03
Klasa LinkedList – przykład 3/3
• Efekt działania programu:
Lista: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20]
Lista: [{1}, {2}, {3}, 4, {5}, 6, {7}, 8, 9, 10, {11}, 12, {13}, 14, 15, 16,
{17}, 18, {19}, 20]
Lista: [{1}, {2}, {3}, {5}, {7}, {11}, {13}, {17}, {19}]
49
LinkedList jako stos oraz jako kolejka
• metody zdefiniowane w klasie LinkedList pozwalające na
wykorzystanie obiektu w charakterze stosu lub kolejki (metody
te nie są częścią interfejsu List)
50
25
2009-11-03
Stos
wierzchołek
stosu
51
Stos – przykładowy program 1/3
import java.util.*;
public class Stos {
public static void main(String[] args) {
LinkedList st = new LinkedList();
st.addFirst("Poniedzialek");
st.addFirst("Wtorek");
st.addFirst("Sroda");
//sprawdzenie elementu znajdujacego się
//na wierzcholku stosu (bez usuwania go ze stosu)
System.out.println("Na wierzcholku stosu znajduje sie: " +
st.getFirst());
52
26
2009-11-03
Stos – przykładowy program 2/3
//wyswietlenie stosu
System.out.println("Elementy: " + st);
//pobieranie elementow ze stosu (z usuwaniem)
System.out.println("\nPobieranie elementow ze
stosu\n");
while(!st.isEmpty())
{
System.out.println(" Pobrany element to: " +
st.removeFirst());
System.out.println(" Zawartosc stosu: " + st);
System.out.println();
}
}
}
53
Stos – przykładowy program 3/3
Efekt działana programu:
Na wierzcholku stosu znajduje sie: Sroda
Elementy: [Sroda, Wtorek, Poniedzialek]
Pobieranie elementow ze stosu
Pobrany element to: Sroda
Zawartosc stosu: [Wtorek, Poniedzialek]
Pobrany element to: Wtorek
Zawartosc stosu: [Poniedzialek]
Pobrany element to: Poniedzialek
Zawartosc stosu: []
54
27
2009-11-03
Kolejka
początek
kolejki
koniec
kolejki
55
Kolejka – przykładowy program 1/4
import java.util.*;
public class Kolejka {
public static void main(String[] args) {
LinkedList kol = new LinkedList();
kol.addLast("Poniedzialek");
kol.addLast("Wtorek");
kol.addLast("Sroda");
56
28
2009-11-03
Kolejka – przykładowy program 2/4
//sprawdzenie elementu znajdujacego się
//na poczatku kolejki (bez usuwania go z kolejki)
System.out.println("Na poczatku kolejki
znajduje sie:" + kol.getFirst());
//wyswietlenie kolejki
System.out.println("Elementy: " + kol);
//pobieranie elementow z kolejki (z usuwaniem)
System.out.println("\nPobieranie elementow
z kolejki\n");
57
Kolejka – przykładowy program 3/4
while(!kol.isEmpty()) {
System.out.println(" Pobrany element to: " +
kol.removeFirst());
System.out.println(" Zawartosc kolejki: " +
kol);
System.out.println();
}
}
}
58
29
2009-11-03
Kolejka – przykładowy program 4/4
Efekt działania programu:
Na poczatku kolejki znajduje sie: Poniedzialek
Elementy: [Poniedzialek, Wtorek, Sroda]
Pobieranie elementow z kolejki
Pobrany element to: Poniedzialek
Zawartosc kolejki: [Wtorek, Sroda]
Pobrany element to: Wtorek
Zawartosc kolejki: [Sroda]
Pobrany element to: Sroda
Zawartosc kolejki: []
59
Tablica asocjacyjna
• tablica asocjacyjna: kolekcja par: klucz - wartośd (wartości
klucza nie mogą się powtarzad),
• tablica asocjacyjna jest opisana za pomocą interfejsu Map.
60
30
2009-11-03
Interfejsy Map oraz Map.Entry
metoda entrySet zwraca zbiór elementów tablicy asocjacyjnej.
Każdy element implementuje interfejs Map.Entry.
61
Implementacja tablic asocjacyjnych
• Tablice asocjacyjne zaimplementowane są w postaci klas:
– HashMap
– TreeMap – uporządkowana tablica asocjacyjna
62
31
2009-11-03
Klasa HashMap
• do przechowywania kluczy stosowana jest tablica z
haszowaniem; w związku z tym obiekty spełniające rolę kluczy
muszą posiadad prawidłowo zaimplementowaną funkcję
hashCode() oraz equals().
• klucze nie mogą się powtarzad;
• przeszukiwanie zbioru kluczy jest znacznie szybsze niż
przeszukiwanie zbioru obiektów.
63
HashMap – przykład 1/4
import java.util.*;
public class TablicaAsocjacyjna
{
public static void main(String [] args)
{
Map asoc = new HashMap();
asoc.put(new Integer(1),"Jeden");
asoc.put(new Integer(2),"Dwa");
asoc.put(new Integer(3),"Trzy");
asoc.put(new Integer(4),"Cztery");
asoc.put(new Integer(5),"Piec");
System.out.println("Tablica asocjacyjna: " + asoc);
64
32
2009-11-03
HashMap – przykład 2/4
System.out.println("czy jest klucz '44' - " +
asoc.containsKey(new Integer(44)));
System.out.println("czy jest klucz '1' - " +
asoc.containsKey(new Integer(1)));
System.out.println("element o kluczu '44': " +
asoc.get(new Integer(44)));
System.out.println("element o kluczu '1': " +
asoc.get(new Integer(1)));
System.out.println("czy jest wartosc 'Dwa': " +
asoc.containsValue("Dwa"));
System.out.println("czy jest wartosc 'Siedem': " +
asoc.containsValue("Siedem"));
65
HashMap – przykład 3/4
Set zawartosc = asoc.entrySet();
Iterator iter = zawartosc.iterator();
Map.Entry element;
System.out.println("\nZawartosc tablicy asocjacyjnej\n");
while(iter.hasNext())
{
element = (Map.Entry) iter.next();
System.out.print("klucz=" + element.getKey());
System.out.println(" wartosc=" +
element.getValue());
}
}
}
66
33
2009-11-03
HashMap – przykład 4/4
Efekt działania programu:
Tablica asocjacyjna: {2=Dwa, 4=Cztery, 1=Jeden, 3=Trzy, 5=Piec}
czy jest klucz '44' - false
czy jest klucz '1' - true
element o kluczu '44': null
element o kluczu '1': Jeden
czy jest wartosc 'Dwa': true
czy jest wartosc 'Siedem': false
Zawartosc tablicy asocjacyjnej
klucz=2 wartosc=Dwa
klucz=4 wartosc=Cztery
klucz=1 wartosc=Jeden
klucz=3 wartosc=Trzy
klucz=5 wartosc=Piec
67
Klasa TreeMap
• elementy uporządkowane są według wartości kluczy
• do przechowania kluczy wykorzystywane jest drzewo
poszukiwao binarnych
• Porządkowanie obiektów:
– naturalne (kluczami są obiekty implementujące interfejs Comparable),
– zdefiniowane za pomocą komparatora
68
34
2009-11-03
Porządkowanie naturalne
import java.util.*;
public class TreeMapTest1 {
public static void main(String [] args) {
Map kraje = new TreeMap();
kraje.put("Niemcy","Berlin");
kraje.put("Polska","Warszawa");
kraje.put("Czechy","Praga");
kraje.put("Hiszpnia","Madryt");
kraje.put("Grecja","Ateny");
kraje.put("Wlochy","Rzym");
System.out.println(kraje);
}
}
Wyniki działania programu:
{Czechy=Praga, Grecja=Ateny, Hiszpnia=Madryt, Niemcy=Berlin, Polska=Warszawa,
Wlochy=Rzym}
69
Zastosowanie komparatora 1/2
import java.util.*;
class Porzadkowanie implements Comparator
{
public int compare(Object o1, Object o2)
{
return -1 * ((String) o1).compareTo((String) o2);
}
}
70
35
2009-11-03
Zastosowanie komparatora 2/2
public class TreeMapTest2 {
public static void main(String [] args) {
Porzadkowanie p = new Porzadkowanie();
Map kraje = new TreeMap(p);
kraje.put("Niemcy","Berlin");
kraje.put("Polska","Warszawa");
kraje.put("Czechy","Praga");
kraje.put("Hiszpnia","Madryt");
kraje.put("Grecja","Ateny");
kraje.put("Wlochy","Rzym");
System.out.println(kraje);
}
}
Wyniki działania programu:
{Wlochy=Rzym, Polska=Warszawa, Niemcy=Berlin, Hiszpnia=Madryt, Grecja=Ateny, Czechy=Praga}
71
Wyznaczanie wartości wyrażenia przy wykorzystaniu ONP
• Sposób realizacji obliczeo:
– określenie postaci wyrażenia,
– przekształcenie wyrażenia do postaci równoważnej zapisanej za
pomocą Odwrotnej Notacji Polskiej (ONP),
– sprawdzenie poprawności wyrażenia zapisanego w ONP,
– wyznaczenie wartości wyrażenia zapisanego w ONP.
• Podstawową strukturą danych wykorzystywaną w trakcie
obliczeo jest stos.
72
36
2009-11-03
Odwrotna Notacja Polska
• Twórcą jest Jan Łukasiewicz, 1921
• ONP jest notacją postfiksową (operator podawany jest po
argumentach)
• Przykłady wyrażeo w notacji infiksowej i postfiksowej:
A+BAB+
(B - C) * D  B C - D *
73
Konwersja do postaci postfiksowej
• Podstawowe zasady obowiązujące w trakcie konwersji:
– Kolejnośd argumentów w postaci infiksowej i postfiksowej jest taka
sama.
– Zmianie ulega kolejnośd operatorów.
– Wyrażenie w postaci infiksowej jest analizowane od lewej do prawej
strony.
– Po odczytaniu argumentu jest on natychmiast zapisywany do
wyrażenia w postaci postfiksowej.
– Odczytane operatory przechowywane są na stosie.
74
37
2009-11-03
Konwersja do postaci postfiksowej
• Algorytm konwersji:
1.
2.
3.
4.
Usunięcie wszystkich elementów ze stosu (na początku konwersji stos
musi byd pusty).
Jeżeli odczytany został operator i stos jest pusty to operator jest
umieszczany na stosie.
Jeżeli odczytany został operator o wyższym priorytecie niż operator
znajdujący się na wierzchołku stosu to odczytany operator jest
umieszczany na stosie. W przeciwnym przypadku ze stosu usuwany jest
operator znajdujący się na jego wierzchołku i umieszczany jest on na
koocu wyrażenia w postaci postfiksowej. Dalszy sposób postępowania z
odczytanym operatorem jest określony przez ponowna realizację punktu
2 lub punktu 3.
Jeżeli został osiągnięty koniec analizowanego wyrażenia zapisanego w
postaci infiksowej to ze stosu usuwane są kolejno znajdujące się tam
operatory i są dopisywane do wyrażenia w postaci postfiksowej.
75
Analiza przykładowego wyrażenia
76
38
2009-11-03
Wyrażenia z nawiasami
1. Jeżeli odczytanym elementem wyrażenia zapisanego w
postaci infiksowej jest lewy nawias to jest on umieszczany na
stosie. Nawiasy traktowane są w podobny sposób jak
operatory. Priorytet nawiasu jest niższy od priorytetu
każdego innego operatora.
2. Jeżeli odczytanym elementem wyrażenia zapisanego w
postaci infiksowej jest prawy nawias to ze stosu usuwane są
kolejno znajdujące się na nim operatory i dopisywane są one
do wyrażenia w postaci postfiksowej. Operacja usuwania
operatorów ze stosu jest wykonywana aż do chwili, gdy na
wierzchołku stosu znajdzie się lewy nawias. Wówczas
odpowiadające sobie nawiasy są usuwane (prawy z
wyrażenia infiksowego, zaś lewy ze stosu).
77
Przykład 1/3
78
39
2009-11-03
Przykład 2/3
79
Przykład 3/3
80
40
2009-11-03
Ranga wyrażenia
• Przez stopieo operatora rozumie się liczbę wymaganych przez
niego argumentów (np. stopieo operatora * wynosi 2).
• Każdemu wyrażeniu postfiksowemu można przypisad
współczynnik zwany rangą wyrażenia.
• Sposób obliczania rangi:
1.
2.
3.
Ranga symbolu (wartości występującej w wyrażeniu) wynosi 1.
Ranga operatora n-tego stopnia wynosi 1 - n.
Ranga ciągu symboli i operatorów jest równa sumie rang
poszczególnych symboli i operatorów.
81
Poprawnośd wyrażenia arytmetycznego
• Konwersja błędnie zapisanego wyrażenia w postaci infiksowej
prowadzi do utworzenia błędnego wyrażenia w postaci
postfiksowej.
• Procedura sprawdzająca poprawnośd wyrażenia może
analizowad wyłącznie postad postfiksową.
• Wyrażenie postfiksowe jest poprawne wtedy i tylko wtedy,
gdy ranga tego wyrażenia jest równa 1 i ranga dowolnej
głowy właściwej wyrażenia jest większa lub równa 1.
82
41
2009-11-03
Poprawnośd przykładowych wyrażeo
Infix: a - b * c
Postfix: a b c * poprawny
Infix: a + * b
Postfix: a b * +
błędny
Infix: a*+bc
Postfix: a * bc+
błędny
83
Wartośd wyrażenia w ONP
• W trakcie analizy wyrażenia od lewej do prawej strony:
– odczytane argumenty są umieszczane na stosie,
– po odczytaniu operatora odczytywana jest ze stosu odpowiednia liczba
argumentów, wykonywane jest działanie i wynik umieszczany jest
ponownie na stosie.
84
42
2009-11-03
Wartośd przykładowego wyrażenia
85
43