Föreläsning 4 Innehåll. Abstrakta datatypen lista. Implementering av listor. Abstrakt datatypen lista. Abstrakt datatyp

Relevanta dokument
Föreläsning 4 Innehåll

ADT Kö. Seminarium 4 Köer och Stackar Innehåll. Operationer. ADT Stack. Definition. Definition

Föreläsning 3-4 Innehåll

Föreläsning 2. Länkad lista och iterator

Föreläsning 2. Länkad lista och iterator

Abstrakt datatyp. -Algoritmer och Datastrukturer- För utveckling av verksamhet, produkter och livskvalitet.

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 3 Jonas Lindgren, Institutionen för Datavetenskap, LiU

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 3 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Datastrukturer. föreläsning 3. Stacks 1

Föreläsning 4. ADT Kö Kö JCF Kö implementerad med en cirkulär array Kö implementerad med en länkad lista

Föreläsning 2 Innehåll

Seminarium 2 Introduktion till Java Collections Framework Innehåll. Generik Bakgrund. Exempel på en generisk klass java.util.arraylist.

Seminarium 3 Introduktion till Java Collections Framework Innehåll. Generik Bakgrund. Exempel på en generisk klass java.util.arraylist.

Java Collections Framework. Föreläsning 2 Innehåll. Java Collections Framework interface hierarki. Java Collections Framework interface hierarki

Stackar, köer, iteratorer och paket

F12 - Collections. ID1004 Objektorienterad programmering Fredrik Kilander

Föreläsning 14 Innehåll

Länkade strukturer. (del 2)

Föreläsning 2 Innehåll. Generiska klasser. Generik i Java. Varför generiska klasser Bakgrund

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 2. Laboration 2 Datastrukturer En liten uppgift Frågor

Listor. Koffman & Wolfgang kapitel 2, avsnitt , och 2.9

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 2. Länkade listor Stackar Köer MyList Iteratorer Lab 2 Exceptions Paket

Föreläsning 3 Innehåll. Generiska klasser. Icke-generisk lista ArrayList, skiss av implementering. Icke-generisk lista Risk för fel

Datastrukturer. Arrayer. Arrayer. Arrayer. Array av arrayer. Array av arrayer

Föreläsning 3 Datastrukturer (DAT037)

Föreläsning 2 Datastrukturer (DAT037)

Föreläsning 7 Innehåll. Rekursion. Rekursiv problemlösning. Rekursiv problemlösning Mönster för rekursiv algoritm. Rekursion. Rekursivt tänkande:

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 5 Erik Nilsson, Institutionen för Datavetenskap, LiU

Föreläsning Datastrukturer (DAT036)

Föreläsning 2 Datastrukturer (DAT037)

Länkade strukturer, parametriserade typer och undantag

Föreläsning 4. ADT Kö Kö JCF Kö implementerad med en cirkulär array Kö implementerad med en länkad lista Läsanvisningar och uppgifter

Tommy Färnqvist, IDA, Linköpings universitet

Föreläsning 2 Innehåll

Hitta k största bland n element. Föreläsning 13 Innehåll. Histogramproblemet

Java Collections Framework. Föreläsning 2 Innehåll. Java Collections Framework interface hierarki. Java Collections Framework interface hierarki

Föreläsning 9 Innehåll

Föreläsning 10. ADT:er och datastrukturer

Datastrukturer i kursen. Föreläsning 8 Innehåll. Träd rekursiv definition. Träd

Föreläsning 3 Datastrukturer (DAT037)

Objektsamlingar i Java

Föreläsning 3. Stack

Tentamen, EDA690 Algoritmer och Datastrukturer, Helsingborg

ADS : STACK ADT: STACK. Stack och Kö -Implementering - Tilllämpningar. Oftast förekommande metoder i Stack. TopOfStack

Lite om felhantering och Exceptions Mer om variabler och parametrar Fält (eng array) och klassen ArrayList.

Föreläsning 9 Innehåll

Föreläsning 3: Abstrakta datastrukturer, kö, stack, lista

DAT043 Objektorienterad Programmering

Inlämningsuppgiften. Föreläsning 9 Innehåll. Träd. Datastrukturer i kursen

Övning vecka 6. public void method2() { //code block C method3(); //code block D }//method2

public static void mystery(int n) { if (n > 0){ mystery(n-1); System.out.print(n * 4); mystery(n-1); } }

Föreläsning 13 Innehåll

Interface. Interface. Tobias Wrigstad (baserat på bilder från Tom Smedsaas) 3 december 2010

Det finns en referensbok (Java) hos tentavakten som du får gå fram och läsa men inte ta tillbaka till bänken.

EDAA20 Föreläsning Klassen ArrayList. Viktiga operationer på ArrayList. Generisk klass

Saker du ska kunna Föreläsning 13 & 14

DAT043 - föreläsning 8

Lösningsförslag till tentamen i EDAA01 programmeringsteknik fördjupningkurs

ADT Prioritetskö. Föreläsning 13 Innehåll. Prioritetskö vs FIFO-kö. Prioritetskö Exempel på användning. Prioritetsköer och heapar

Föreläsning 1. Abstrakta datatyper, listor och effektivitet

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 6 Erik Nilsson, Institutionen för Datavetenskap, LiU

Abstrakta datatyper. Primitiva vektorer. Deklarera en vektor

Föreläsning Datastrukturer (DAT036)

OOP Objekt-orienterad programmering

Samlingar Collection classes

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 6 Erik Nilsson, Institutionen för Datavetenskap, LiU

Programmering för språkteknologer II, HT2014. Rum

Tentamen i Algoritmer & Datastrukturer i Java

Repetition av OOP- och Javabegrepp

2. Palindrom. Exempel: 1,2,3,2,1 är ett palindrom, och även 0, men inte 1,2,3,1,2,3.

Diskutera. Hashfunktion

Repetition av OOP- och Javabegrepp

ADT Prioritetskö. Föreläsning 12 Innehåll. Prioritetskö. Interface för Prioritetskö. Prioritetsköer och heapar

Sammansatta datatyper Generics: Parametrisk polymorfism

So far... For recursive and iterative programs. Bubble, insertion, selection, quick, merge, counting

Lösningsförslag till tentamen i EDA690 Algoritmer och Datastrukturer, Helsingborg

Föreläsning 3 Innehåll

Diskutera Sortera objekt

Tentamen, EDA501 Programmering M L TM W K V

Föreläsning 5-6 Innehåll. Exempel på program med objekt. Exempel: kvadratobjekt. Objekt. Skapa och använda objekt Skriva egna klasser

Generisk klass med typparameter Inre klass - ListIterator

Föreläsning 5-6 Innehåll

Föreläsning 10 Innehåll

Dagens program. Programmeringsteknik och Matlab. Objektorienterad programmering. Vad är vitsen med att ha både metoder och data i objekten?

Föreläsning 11 Innehåll

Tentamen, EDAA01 Programmeringsteknik fördjupningskurs

Tentamen, Algoritmer och datastrukturer

Föreläsning 3. Stack

Lösningsförslag till tentamen Datastrukturer, DAT037,

Ett problem. Kontrollstrukturer och arrayer. Arrayer. Lösningen. Arrayer och hakparanteser. Exempel int[] results; results = new int[10]; // 0..

Inlämningsuppgift och handledning

Laboration A Objektsamlingar

Föreläsning 10 Innehåll

Objektorienterad Programkonstruktion. Föreläsning 9 30 nov 2016

Föreläsning 7. Träd och binära sökträd

Föreläsning 11 Innehåll. Diskutera. Binära sökträd Definition. Inordertraversering av binära sökträd

Föreläsning 3-4 Innehåll. Diskutera. Metod. Programexempel med metod

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 4 Erik Nilsson, Institutionen för Datavetenskap, LiU

Föreläsning 4. Kö Implementerad med array Implementerad med länkad lista Djup kontra bredd Bredden först mha kö

Tentamen. 2D4135 vt 2005 Objektorienterad programmering, design och analys med Java Lördagen den 28 maj 2005 kl

Transkript:

Föreläsning 4 Innehåll Abstrakta datatypen lista Definition Abstrakta datatypen lista egen implementering Datastrukturen enkellänkad lista Nästlade klasser statiska nästlade klasser inre klasser Listklasser i Java Implementera abstrakta datatyperna stack och kö med vektor eller enkellänkad lista. En lista är en följd av. Det finns en före-efter-relation mellan en. Begrepp som första et i listan, efterföljaren till visst ilistan ärmeningsfulla.detfinnsalltsåettpositionsbegrepp. Definitionen innebär inte att en är sorterade på något visst sätt t.ex. i storleksordning. :a et :a et :e et 4:e et Datavetenskap (LTH) Föreläsning 4 VT 08 / 4 Datavetenskap (LTH) Föreläsning 4 VT 08 / 4 Abstrakt datatypen lista Implementering av listor Abstrakt datatyp En abstrakt modell tillsammans med de operationer man kan utföra på den. Abstrakt modell: lista Operationer på modellen: Lägga in i listan (först, sist ) Ta bort ett ur listan Undersöka om ett visst finns i listan Ta reda på ett et i listan (första, sista ) Undersöka om listan tom En vektor kan användas för att hålla reda på listans. 0 Ett annat sätt är att utnyttja länkad datastruktur. I en länkad struktur består listan av noder som har en referens till efterföljaren (och ev. till föregångaren). Datavetenskap (LTH) Föreläsning 4 VT 08 / 4 Datavetenskap (LTH) Föreläsning 4 VT 08 4 / 4

Egen implementering av listor från grunden Vektor Egen implementering av listor från grunden Enkellänkad lista size a 0 4 5 6 7 8 9 first null objekt som satts in i vektorn objekt som satts in i listan Datavetenskap (LTH) Föreläsning 4 VT 08 5 / 4 Datavetenskap (LTH) Föreläsning 4 VT 08 6 / 4 Enkellänkad lista Implementering public class SingleLinkedList<E> { private ListNode<E> first; // referens till första noden // null om listan är tom..metoder.. /* Statisk nästlad klass. Representerar en nod som innehåller ett av typ E. */ private static class ListNode<E> { private E ; // data som lagras private ListNode<E> ; // refererar till nästa nod private ListNode(E e) { = e; = null; Datavetenskap (LTH) Föreläsning 4 VT 08 7 / 4 Nästlade klasser i Java Klasser kan deklareras inuti andra klasser (nästlade klasser). Används oftast när den nästlade klassen bara är meningsfull för den omgivande klassen. Användare behöver oftast inte känna till existensen av den nästlade klassen. En nästlad klass kan deklareras private om den bara ska användas i den omgivande klassen. Även konstruktorn kan då vara private. I den omgivande klassen har man tillgång till allt i den nästlade klassen (även det som är private). Det finns två typer av nästlade klasser: statiska nästlade klasser inre klasser (eng: inner classes). Datavetenskap (LTH) Föreläsning 4 VT 08 8 / 4

Statiska nästlade klasser public class OuterClass { public void p() { NestedClass x = new NestedClass(); private static class NestedClass { private NestedClass() { En statisk nästlad klass kan bara komma åt statiska attribut och statiska metoder i den omgivande klassen. Datavetenskap (LTH) Föreläsning 4 VT 08 9 / 4 Att skapa objekt av nästlade klasser Inre klasser public class OuterClass { private int i; public void p() { InnerClass x = new InnerClass(); private class InnerClass { private InnerClass() { private void q() { int b = i; ; // Här används i från OuterClass! Ett objekt av en inre klass kan komma åt allt i det objekt av den omgivande klassen som skapade objektet av den inre klassen. Datavetenskap (LTH) Föreläsning 4 VT 08 0 / 4 Att skapa objekt av nästlade klasser Statiska nästlade klasser Om den nästlade klassen är statisk: Görs oftast bara i den omgivande klassen. Då blir det samma syntax som vanligt. Exempel finns på föregående bilder. Man kan skapa objekt av nästlade klasser även utanför den omgivande klassen. Kräver dock att den nästlade klassen och dess konstruktor är public. Detaljer på nästa bild. public class OuterClass { public static class NestedClass { public NestedClass() { så skapas en instans av den nästlade klassen med följande syntax: OuterClass.NestedClass x = new OuterClass.NestedClass(); Datavetenskap (LTH) Föreläsning 4 VT 08 / 4 Datavetenskap (LTH) Föreläsning 4 VT 08 / 4

Att skapa objekt av nästlade klasser Inre klasser Om den nästlade klassen är en inre klass: public class OuterClass { public class InnerClass { public InnerClass() { så kan instanser av den inre klassen bara skapas genom ett objekt av den yttre klassen: OuterClass a = new OuterClass(); OuterClass.InnerClass b = a.new InnerClass(); Åter till implementeringen av listor På följande bilder visas implementeringar av några metoder i klassen SingeLinkedList. public class SingleLinkedList<E> { private ListNode<E> first; private static class ListNode<E> { private E ; // data som lagras private ListNode<E> ; // refererar till nästa nod Datavetenskap (LTH) Föreläsning 4 VT 08 / 4 Datavetenskap (LTH) Föreläsning 4 VT 08 4 / 4 Exempel på metoder i en enkellänkad lista Insättning och borttagning först i listan Länka in en ny nod innehållande et x först ilistan: public void addfirst(e x) { ListNode<E> n = new ListNode<E>(x); n. = first; first = n; Tag bort första noden i listan, returnera dess innehåll: public E removefirst() { if (first == null) { throw new NoSuchElementException(); ListNode<E> temp = first; first = first.; return temp.; Datavetenskap (LTH) Föreläsning 4 VT 08 5 / 4 Traversering av en i listan Exempel: metoden tostring Returnera en sträng som representerar listan: public String tostring() { StringBuilder sb = new StringBuilder(); sb.append( [ ); ListNode<E> p = first; while (p!= null) { sb.append(p..tostring()); if (p.!= null) { sb.append(", "); p = p.; sb.append( ] ); return sb.tostring(); Datavetenskap (LTH) Föreläsning 4 VT 08 6 / 4

Traversering av en i listan Mönster Diskutera ListNode<E> p = first; while (p!= null) { p = p.; Antag att vi ska skriva metoder addlast och removelast för att sätta in och ta bort sist listan. Hur ska vi lösa de problemen? Vilka specialfall finns? Datavetenskap (LTH) Föreläsning 4 VT 08 7 / 4 Datavetenskap (LTH) Föreläsning 4 VT 08 8 / 4 Exempel på metoder i en enkellänkad lista Insättning sist i listan Söka upp sista noden i listan Mönster Länka in en ny nod innehållande et x sist ilistan: public void addlast(e x) { ListNode<E> n = new ListNode<E>(x); if (first == null) { first = n; else { ListNode<E> p = first; while(p.!= null) { p = p.; p. = n; if (first == null) { else { ListNode<E> p = first; while (p.!= null) { p = p.; // Här refererar p till sista noden Datavetenskap (LTH) Föreläsning 4 VT 08 9 / 4 Datavetenskap (LTH) Föreläsning 4 VT 08 0 / 4

Exempel på metoder i en enkellänkad lista Borttagning sist i listan Diskutera public E removelast() { if (first == null) { // tom lista throw new NoSuchElementException(); if (first. == null) { // ett ListNode<E> temp = first; first = null; return temp.; ListNode<E> p = first; // minst två ListNode<E> pre = null; while (p.!= null) { pre = p; p = p.; pre. = null; return p.; Datavetenskap (LTH) Föreläsning 4 VT 08 / 4 Implementering med länkad struktur Kommentarer Exemplen visar att det är viktigt att tänka på specialfall. Vissa operationer blir krångliga i den enkellänkade implementeringen. Dessa kan förenklas om man i varje nod också har en referens till föregångaren. Detta kallas dubbellänkade listor. first Man kan förenkla implementeringar av vissa operationer ytterligare genom att ha ett speciellt ("huvud") i början av listan. Två av metoderna vi implementerat, add och removelast, är långsammare än motsvarande metoder för att sätta in och ta bort i början av listan. Både add och removelast innehåller en loop. Ge förslag på hur man kan implementera listklassen så att dessa loopar kan tas bort. Datavetenskap (LTH) Föreläsning 4 VT 08 / 4 Traversering av listor iteratorer Användare av en listklass behöver möjlighet att gå igenom en i listan. Låt därför SingleLinkedList implementera interfacet Iterable: public class SingleLinkedList<E> implements Iterable<E> { Lägg till metoden Iterator<E> iterator() i klassen SingleLinkedList. Metoden iterator ska skapa och returnera ett iterator-objekt. Skriv en (inre) klass som implementerar interfacet Iterator enligt mönstret: private class MyListIterator implements Iterator<E> { Datavetenskap (LTH) Föreläsning 4 VT 08 / 4 Datavetenskap (LTH) Föreläsning 4 VT 08 4 / 4

Interfacet Iterator metoder Iteratorklass Inre klassen MyListIterator /** Returns true if the iteration has more s. */ boolean hasnext(); /** Returns the in the iteration. */ E (); /** Removes from the underlying collection the returned by the iterator (optional). */ default void remove(); Metoder deklarerade default är redan implementerade. Default-metoden remove genererar UnsupportedOperationException. private class MyListIterator implements Iterator<E> { private ListNode<E> pos; private MyListIterator() {pos = first; public boolean hasnext() {return pos!= null; public E () { if (hasnext()) { ListNode<E> temp = pos; pos = pos.; return temp.; else { throw new NoSuchElementException(); Datavetenskap (LTH) Föreläsning 4 VT 08 5 / 4 Datavetenskap (LTH) Föreläsning 4 VT 08 6 / 4 Metoden iterator() Klassen SingleListIterator public class SingleLinkedList<E> implements Iterable<E> { private ListNode<E> first; public Iterator<E> iterator() { return new MyListIterator(); private class MyListIterator implements Iterator<E> { Användning av iterator Exempel Nu kan vi iterera genom vår lista: SingleLinkedList<String> list = new SingleLinkedList<String>(); // sätt in några String-objekt i listan Iterator<String> itr = list.iterator(); while (itr.hasnext()) { String s = itr.(); Eftersom vår klass SingleLinkedList implementerar interfacet Iterable kan vi också använda foreach -satsen: for (String s : list) { Datavetenskap (LTH) Föreläsning 4 VT 08 7 / 4 Datavetenskap (LTH) Föreläsning 4 VT 08 8 / 4

Listklasser i java.util Det finns två konkreta generiska klasser i Javas API för listhantering. Båda implementerar interfacet List. <<Interface>> Iterable Diskutera Nu när vi implementerat en egen listklass kan vi jämföra olika listimplementeringar: ArrayList implementeras med hjälp av en vektor: ArrayList<E>, som implementerats med vektor LinkedList<E>, som implementerats med en dubbel-länkad cirkulär struktur <<Interface>> Collection <<Interface>> List 0 4 5 6 7 8 9 Inuti LinkedList används en cirkulär, dubbellänkad struktur: ArrayList LinkedList Fördelar, nackdelar? Datavetenskap (LTH) Föreläsning 4 VT 08 9 / 4 Datavetenskap (LTH) Föreläsning 4 VT 08 0 / 4 ArrayList vs LinkedList Implementera abstrakta datatyperna stack och FIFO-kö ArrayList De indexerade metoderna get(int idx) och set(int idx, E ) är effektiva i ArrayList. Däremot är insättningar och borttagningar (utom sist i listan) långsamma eftersom måste flyttas. LinkedList De indexerade metoderna är långsamma eftersom listan måste stegas igenom tills önskat nås. När man väl hittat rätt plats i listan är insättningar och borttagningar snabba. Nod-objekten kräver extra minne och hantering. Vi har tidigare sett ett exempel hur man kan skriva en stack-klass genom att internt använda LinkedList eller ArrayDeque. Fördelen är att det är enkelt och koden blir kort. Men det bli dubbla metodanrop. Om vi anropar push i vår stackklass, så anropas också push i LinkedList, En onödigt komplicerad datastruktur används. Exempel: Datastrukturen i LinkedList är vald så att operationerna på listan ska bli effektiva. Det ät onödigt med dubbellänkad lista för att implementera en stack. Istället kan man använda en vektor eller en enkellänkad lista för att implementera de abstrakta datatyperna stack och FIFO-kö. Datavetenskap (LTH) Föreläsning 4 VT 08 / 4 Datavetenskap (LTH) Föreläsning 4 VT 08 / 4

Diskutera Implementering av stack Enkellänkad datastruktur Hur kan man använda en enkellänkad lista för att implementera en stack? Hur kan man använda en vektor lista för att implementera en stack? Enkellänkad datastruktur för stack: Stacken representeras av referens till första noden. Alla operationer kan då utföras på konstant tid, oberoende av stackens storlek. Behöver extra utrymme för -referenser. first Datavetenskap (LTH) Föreläsning 4 VT 08 / 4 Datavetenskap (LTH) Föreläsning 4 VT 08 4 / 4 Enkellänkad implementering av stack Vektorimplementering av stack s = new MyStack<Integer>(); s.push(); s.push(); s.push(); int i = s.pop() // i får värdet first = null first first first first Vektorimplementering av stack: Stacken representeras av vektor och index för nästa insättning (initialt 0). Ger konstant tid för metoderna så länge vektorns storlek räcker. Om man dubblar vektorns storlek varje gång den inte räcker till, kan man visa att metoderna fortfarande i medeltal går att utföra på konstant tid. Efter dubblering är bara halva utrymmet i vektorn utnyttjat. Datavetenskap (LTH) Föreläsning 4 VT 08 5 / 4 Datavetenskap (LTH) Föreläsning 4 VT 08 6 / 4

Vektorimplementering av stack Implementering av kö Enkellänkad datastruktur s = new MyStack<Integer>(); size = 0 s.push(); s.push(); s.push() size = size = Enkellänkad datastruktur för FIFO-kö: Kön representeras av referenser till första och sista noden. Alla operationer kan då utföras på konstant tid, oberoende av köns längd. Behöver extra utrymme för -referenser. int i = s.pop() // i får värdet size = first s.push(4); 4 size = Datavetenskap (LTH) Föreläsning 4 VT 08 7 / 4 Datavetenskap (LTH) Föreläsning 4 VT 08 8 / 4 Enkellänkad implementering av kö Vektorimplementering av kö q = new MyQueue<Integer>(); first = = null q.offer(); q.offer(); q.offer(); first first first Vektorimplementering av kö: Vektorn används cirkulärt; första platsen i vektorn anses vara efterföljare till sista platsen. Kön representeras av vektorn samt index för första (äldsta) et front index för sista (yngsta) et rear antalet size Även här kan vi behöva skapa större vektor när antalet blivit för stort. int i = q.poll() // i får värdet first Datavetenskap (LTH) Föreläsning 4 VT 08 9 / 4 Datavetenskap (LTH) Föreläsning 4 VT 08 40 / 4

Vektorimplementering av kö Exempel på vad du ska kunna q = new MyQueue<Integer>(); q.offer(); q.offer(); q.offer(); q.offer(4); q.offer(5); int i = q.poll() // i får värdet q.offer(6); front = 0, rear = -, size = 0 front = 0, rear = 0, size = 4 5 front = 0, rear = 4, size = 5 4 5 front =, rear = 4, size = 4 6 4 5 front =, rear = 0, size = 5 Implementera en lista effektivt med hjälp av vektor respektive länkade struktur. Förklara vad nästlade och inre klasser är för något samt kunna implementera sådana. Med hjälp av dokumentation använda klasser och interface från Java Collections Framework: List, Queue, Deque, ArrayList, LinkedList, ArrayDeque, Iterator, ListIterator och Iterable Implementera en lista, stack eller kö effektivt med hjälp av vektor respektive länkade struktur. Datavetenskap (LTH) Föreläsning 4 VT 08 4 / 4 Datavetenskap (LTH) Föreläsning 4 VT 08 4 / 4 Datorlaboration Enkellänkad lista Implementera egna generisk klasser som beskriver en FIFO-kö. I en klass ska du delegera till klassen LinkedList. I den andra klassen ska du använda en cirkulär, enkellänkad lista för att hålla reda på en i kön. Utifrån sett ser kön ut så här: Inuti klassen är den uppbyggd så här: size Tips! Rita för att förstå vad som händer i programmet! Innehåll: kö, enkellänkad lista, iterator, testning med JUnit. Datavetenskap (LTH) Föreläsning 4 VT 08 4 / 4