EuraStudy
Samenvattingen/Informatica/Domein B: Grondslagen
Samenvattingen · InformaticaNL · HAVO

Domein B: Grondslagen

Grondslagen is het theoretische hart van informatica: hier leer je wat een algoritme precies is, hoe je de snelheid ervan met de grote-O-notatie inschat, en welke datastructuren, automaten en talen onder alle software liggen. Je oefent met zoeken en sorteren, bouwt bomen en grafen, laat eindige automaten strings accepteren, leidt expressies af met een grammatica en rekent tussen binaire, decimale en hexadecimale getallen. Zo krijg je grip op de denkgereedschappen waarmee je in de rest van het vak programmeert en systemen ontwerpt.

6 Onderdelen·~33 min leestijd·4 Vaardigheden·Niveau Basis 1 · Standaard 3 · Verdieping 2

T·0222 / 12
Examenprofiel
Standaardalgoritmen voor zoeken en sorteren herkennen, naspelen en hun complexiteit in de grote-O-notatie bepalen (O(n), O(\log n), O(n²)).Datastructuren (lijst, stack, queue, boom, graaf, hashtabel) beschrijven en bij een probleem een passende structuur kiezen.Eindige automaten en formele grammatica's lezen: een string accepteren of verwerpen, een string afleiden en een parseboom opstellen.Getallen omrekenen tussen binair, decimaal en hexadecimaal en booleaanse expressies met een waarheidstabel evalueren.
Operatoren:bepaalberekentekenleg uitberedeneertoon aanpas toevul in

basisniveau

Zorg dat je de kernbegrippen kunt benoemen en een algoritme of automaat stap voor stap kunt naspelen op een klein voorbeeld.

verhoogd niveau

Leg verbanden: waarom is iets O(n2)O(n^2)O(n2), hoe hangen automaten en grammatica's samen, en hoe onderbouw je met een waarheidstabel dat twee expressies gelijkwaardig zijn?

Diepte

Leesdiepte: Verdieping

Tekst

Tekstgrootte: Standaard

Inhoud · 6 onderdelen▾
  1. Domein B: Grondslagen
    • 01Algoritmen en complexiteit○
    • 02Sorteeralgoritmen◐
    • 03Datastructuren◐
    • 04Eindige automaten en toestandsmachines●
    • 05Formele talen en grammatica's●
    • 06Getalstelsels en booleaanse logica◐
§ 01

Algoritmen en complexiteit#

●○○BasisLPexamenblad-nl

Groei van complexiteitsklassen

Groei van de complexiteitsklassenSchaubild von O(1), im Bereich x von 1 bis 16, Schaubild von O(log n), Nullstellen bei x = 1, steigend, im Bereich x von 1 bis 16, Schaubild von O(n), steigend, im Bereich x von 1 bis 16, Schaubild von O(n log n), Nullstellen bei x = 1, steigend, im Bereich x von 1 bis 16, Schaubild von O(n^2), steigend, im Bereich x von 1 bis 8, Schaubild von O(2^n), steigend, im Bereich x von 1 bis 6246810121416102030405060O(1)O(log n)O(n)O(n log n)O(n2)O(2n)aantal stappenn (invoergrootte)
Afb. 1Afb. 1 — Hoe het aantal stappen groeit met de invoergrootte n. Hoe hoger de klasse in de rangorde, hoe steiler de kromme stijgt.

Kernpunten

Een algoritme is een eindige, ondubbelzinnige en uitvoerbare beschrijving van de stappen die een probleem oplossen. 'Eindig' betekent dat het na een begrensd aantal stappen stopt met een antwoord; 'ondubbelzinnig' dat elke stap maar op één manier gelezen kan worden, zodat twee mensen (of computers) precies hetzelfde doen; en 'uitvoerbaar' dat elke stap concreet genoeg is om echt uit te voeren. In de informatica formuleren we ze los van een programmeertaal — vaak in pseudocode of een stroomdiagram — zodat we eerst over de méthode kunnen nadenken en pas daarna over de code. Een goed algoritme is bovendien correct (het geeft altijd het juiste antwoord) en het liefst efficiënt (het doet dat met zo min mogelijk werk).
Zoeken is het schoolvoorbeeld waaraan je efficiëntie leert. Lineair zoeken loopt de rij van voor naar achter af en vergelijkt elk element met de gezochte waarde; in het slechtste geval — het element staat achteraan of ontbreekt — kost dat n vergelijkingen bij n elementen. We noteren dat als O(n)O(n)O(n): het werk groeit evenredig met de invoergrootte. Binair zoeken is veel slimmer, maar stelt één eis: de rij moet gesorteerd zijn. Je kijkt naar het middelste element; is dat te groot, dan ligt de gezochte waarde links en gooi je de hele rechterhelft weg, en omgekeerd. Elke vergelijking halveert zo het aantal overgebleven kandidaten. Dat halveren kun je hooguit log⁡2n\log_2 nlog2​n keer doen, dus binair zoeken is O(log⁡n)O(\log n)O(logn).
Om algoritmen eerlijk te vergelijken tellen we niet de seconden — die hangen van de computer af — maar het aantal elementaire stappen als functie van de invoergrootte n. De grote-O-notatie vat die groei samen en gooit bewust details weg: constanten en langzamere termen tellen niet mee, want bij grote n bepaalt de snelst groeiende term het plaatje. Een algoritme dat 3n+503n + 503n+50 stappen doet is gewoon O(n)O(n)O(n), en 2n2+100n2n^2 + 100n2n2+100n is O(n2)O(n^2)O(n2), omdat n2n^2n2 uiteindelijk over 100n100n100n heen groeit. Grote-O zegt dus iets over de vórm van de groei, niet over de precieze snelheid: het is een bovengrens die beschrijft hoe hard het werk oploopt als je probleem groter wordt. Juist dat maakt het zo bruikbaar om te voorspellen of een aanpak bij grote invoer nog werkbaar blijft.
De belangrijkste complexiteitsklassen vormen een vaste rangorde, van zuinig naar onbetaalbaar: O(1)O(1)O(1) (constant — even veel werk, ongeacht n, zoals het opvragen van een array-element via zijn index), O(log⁡n)O(\log n)O(logn) (logaritmisch — halveren, zoals binair zoeken), O(n)O(n)O(n) (lineair — alles één keer langslopen), O(nlog⁡n)O(n \log n)O(nlogn) (de snelheid van goede sorteeralgoritmen), O(n2)O(n^2)O(n2) (kwadratisch — geneste lussen, zoals eenvoudige sorteringen) en O(2n)O(2^n)O(2n) (exponentieel — bijvoorbeeld alle deelverzamelingen proberen). Afbeelding 1 laat zien hoe dramatisch die klassen uiteenlopen; Afbeelding 2 zet er getallen bij. Het verschil is enorm: bij n=1000n = 1000n=1000 doet een O(n)O(n)O(n)-aanpak duizend stappen, O(n2)O(n^2)O(n2) er een miljoen, en O(2n)O(2^n)O(2n) zoveel dat geen computer ter wereld het ooit afmaakt.
Ten slotte moet je altijd zeggen wélk geval je bedoelt. Het best-case is het gunstigste scenario (bij lineair zoeken: het element staat vooraan, één stap), het worst-case het ongunstigste (het staat achteraan of ontbreekt, n stappen) en het average-case het gemiddelde over alle mogelijke invoeren. In de praktijk en bij het schoolexamen kijken we meestal naar het worst-case, omdat dat een gegarandeerde bovengrens geeft: je weet dan zeker dat het nooit erger wordt. Voor binair zoeken is het worst-case O(log⁡n)O(\log n)O(logn), voor lineair zoeken O(n)O(n)O(n) — en juist omdat het worst-case telt, loont het om je gegevens eerst te sorteren als je er daarna vaak in gaat zoeken.
T(n)=O(f(n))T(n) = O\bigl(f(n)\bigr)T(n)=O(f(n))

Grote-O-notatie

T(n)T(n)T(n) is het aantal stappen bij invoergrootte nnn; O(f(n))O(f(n))O(f(n)) geeft een bovengrens op de groei, waarbij constanten en lagere termen wegvallen.

O(1)<O(log⁡n)<O(n)<O(nlog⁡n)<O(n2)<O(2n)O(1) < O(\log n) < O(n) < O(n \log n) < O(n^2) < O(2^n)O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(2n)

Rangorde van de complexiteitsklassen

Voor grote nnn groeit elke klasse sneller dan de vorige; deze volgorde bepaalt welke aanpak bij grote invoer nog haalbaar is.

⌈log⁡21000⌉=10\lceil \log_2 1000 \rceil = 10⌈log2​1000⌉=10

Binair zoeken in 1000 elementen

Je kunt 1000 elementen hooguit tien keer halveren, dus binair zoeken doet maximaal 10 vergelijkingen.

Big-O in getallen

Aantal stappen per complexiteitsklasseTabel met 4 kolommen en 6 rijen, Gegevens: Groeiklasse · n = 10 · n = 100 · n = 1000; O(1) · 1 · 1 · 1; O(log n) · ≈ 3 · ≈ 7 · ≈ 10; O(n) · 10 · 100 · 1000; O(n log n) · ≈ 33 · ≈ 664 · ≈ 9966; O(n²) · 100 · 10 000 · 1 000 000; O(2ⁿ) · 1024 · ≈ 10³⁰ · onhaalbaar, gemarkeerde cel: onhaalbaarGROEIKLASSEN = 10N = 100N = 1000O(1)111O(LOG N)≈ 3≈ 7≈ 10O(N)101001000O(N LOG N)≈ 33≈ 664≈ 9966O(N²)10010 0001 000 000O(2ⁿ)1024≈ 10³⁰onhaalbaar
Afb. 2Afb. 2 — Dezelfde klassen in getallen: bij n = 1000 loopt O(n^2) al in de miljoenen en is O(2^n) onhaalbaar.
Uitgewerkt voorbeeld

Hoeveel stappen doet binair zoeken in 1000 elementen?

Een gesorteerde lijst bevat 1000 elementen. Bepaal het maximale aantal vergelijkingen dat binair zoeken nodig heeft en vergelijk dat met lineair zoeken.

  1. 01Wat doet één stap?

    Binair zoeken vergelijkt de gezochte waarde met het middelste element en gooit daarna de helft van de kandidaten weg. Elke vergelijking halveert dus het zoekgebied.

  2. 02Tel de halveringen

    Van 1000 blijven achtereenvolgens over: 500, 250, 125, 63, 32, 16, 8, 4, 2, 1. Na tien halveringen is er nog één element over.

    1000→500→250→⋯→11000 \to 500 \to 250 \to \dots \to 11000→500→250→⋯→1
  3. 03Reken met de logaritme

    Het aantal halveringen is naar boven afgerond de tweelog van 1000.

    ⌈log⁡21000⌉=⌈9,97⌉=10\lceil \log_2 1000 \rceil = \lceil 9{,}97 \rceil = 10⌈log2​1000⌉=⌈9,97⌉=10
  4. 04Vergelijk met lineair zoeken

    Lineair zoeken doet in het slechtste geval 1000 vergelijkingen (O(n)O(n)O(n)); binair zoeken maar 10 (O(log⁡n)O(\log n)O(logn)) — honderd keer minder werk, mits de lijst gesorteerd is.

Resultaat: Binair zoeken heeft maximaal 10 vergelijkingen nodig, tegen 1000 voor lineair zoeken.

Eindexamen-focus

  • Het grote-O-gedrag van lineair zoeken (O(n)O(n)O(n)) en binair zoeken (O(log⁡n)O(\log n)O(logn)) benoemen én de voorwaarde (gesorteerd) van binair zoeken uitleggen.
  • Van een gegeven stukje (pseudo)code of een lus de complexiteitsklasse bepalen door de dominante term te herkennen.
  • Uitrekenen hoeveel stappen een algoritme maximaal doet voor een concrete n, bijvoorbeeld het aantal halveringen bij binair zoeken.

Veelgemaakte fouten

  • Binair zoeken toepassen op een ongesorteerde rij — dan klopt het halveren niet en mis je de waarde.
  • Constanten en lagere-orde termen laten meetellen in de grote-O (3n23n^23n2 is gewoon O(n2)O(n^2)O(n2)).
  • O(log⁡n)O(\log n)O(logn) en O(nlog⁡n)O(n \log n)O(nlogn) door elkaar halen, of denken dat 'sneller' altijd 'minder code' betekent.

Actieve herhaling

Een gesorteerde lijst bevat 1.000.000 namen. Bepaal hoeveel vergelijkingen lineair zoeken en binair zoeken in het slechtste geval nodig hebben, en leg met de grote-O-notatie uit waarom het verschil zo groot is.

Actief ophalen

Haal de kernpunten op — onthul ze daarna.

Bronnen: Examenprogramma informatica (HAVO) (CvTE / Examenblad)

§ 02

Sorteeralgoritmen#

●●○StandaardLPexamenblad-nl

Bubble sort, pass voor pass

Bubble sort op [5, 1, 4, 2, 8]Tabel met 6 kolommen en 4 rijen, Gegevens: Toestand · pos 1 · pos 2 · pos 3 · pos 4 · pos 5; Start · 5 · 1 · 4 · 2 · 8; Na pass 1 · 1 · 4 · 2 · 5 · 8; Na pass 2 · 1 · 2 · 4 · 5 · 8; Na pass 3 · 1 · 2 · 4 · 5 · 8, gemarkeerde cel: 5TOESTANDPOS 1POS 2POS 3POS 4POS 5START51428NA PASS 114258NA PASS 212458NA PASS 312458
Afb. 3Afb. 3 — Bubble sort op [5, 1, 4, 2, 8]: na elke pass staat het volgende grootste element vast (de gemarkeerde 5 is in pass 1 al bijna naar achteren geborreld). Na pass 3 verandert er niets meer.

Kernpunten

Sorteren — een rij op volgorde zetten — is misschien wel de meest bestudeerde taak in de informatica, omdat het overal opduikt (denk aan zoekresultaten, ranglijsten en het feit dat binair zoeken een gesorteerde rij nodig heeft). De drie klassieke 'eenvoudige' sorteeralgoritmen die je op de HAVO moet kunnen naspelen zijn bubble sort, insertion sort en selection sort. Ze zijn niet de snelste, maar wel makkelijk te begrijpen en juist daardoor ideaal om te leren hoe je een algoritme stap voor stap analyseert. Alle drie werken met geneste herhaling: een buitenste lus die meerdere keren over de rij gaat en een binnenste lus die telkens paren of posities vergelijkt.
Bubble sort ('bellen sorteren') vergelijkt telkens twee buurelementen en verwisselt ze als ze in de verkeerde volgorde staan. In één pass loop je zo van links naar rechts; het grootste element 'borrelt' daarbij vanzelf naar de laatste plaats. Daarna herhaal je het spel op het overgebleven, één korter stuk. Neem de rij [5, 2, 4, 1]. Eerste pass: 5 en 2 wisselen → [2,5,4,1]; 5 en 4 wisselen → [2,4,5,1]; 5 en 1 wisselen → [2,4,1,5]. De 5 staat nu goed. Tweede pass op [2,4,1]: 2 en 4 blijven, 4 en 1 wisselen → [2,1,4,5]. Derde pass: 2 en 1 wisselen → [1,2,4,5]. Klaar. Slim detail: eindigt een pass zónder enkele wissel, dan is de rij al gesorteerd en mag je stoppen.
Insertion sort ('invoegen') bouwt links een gesorteerd deel op en schuift elk volgend element net zo lang naar links tot het op de goede plek zit — precies zoals je speelkaarten in je hand ordent. Selection sort ('selecteren') doet het andersom: het zoekt in het onsorteerde deel telkens het kleinste element en zet dat vooraan, waardoor het gesorteerde deel vanaf links groeit. Voor [5,2,4,1] pikt selection sort eerst de 1 (kleinste) en verwisselt die met de 5 → [1,2,4,5] (hier meteen bijna klaar); insertion sort neemt de 2 en schuift die vóór de 5, dan de 4 tussen 2 en 5, en ten slotte de 1 helemaal naar voren. De drie algoritmen komen bij dezelfde rij op hetzelfde eindresultaat uit, maar verschillen in het aantal wissels en vergelijkingen dat ze onderweg doen.
Waarom zijn deze drie O(n2)O(n^2)O(n2)? Bekijk selection sort: voor het eerste vak vergelijk je met alle overige n − 1 elementen om de kleinste te vinden, voor het tweede met n − 2, dan n − 3, enzovoort. In totaal (n−1)+(n−2)+⋯+1=n(n−1)2(n-1)+(n-2)+\dots+1 = \tfrac{n(n-1)}{2}(n−1)+(n−2)+⋯+1=2n(n−1)​ vergelijkingen — een uitdrukking waarin de n2n^2n2-term domineert, dus O(n2)O(n^2)O(n2). Bubble en insertion sort tellen in het slechtste geval evenveel: bij n elementen ongeveer n2/2n^2/2n2/2 vergelijkingen. Dat betekent dat het werk vierkant oploopt: verdubbel je de rij, dan wordt het ongeveer vier keer zo veel werk. Voor een handjevol getallen is dat prima, maar voor een miljoen elementen zijn deze algoritmen hopeloos traag vergeleken met de O(nlog⁡n)O(n \log n)O(nlogn)-sorteringen (zoals merge sort en quicksort) die je later tegenkomt.
Twee begrippen scheiden de algoritmen verder. Het aantal vergelijkingen en het aantal wissels zijn aparte maten: selection sort doet weinig wissels (hooguit n − 1) maar altijd veel vergelijkingen, terwijl bubble sort juist veel kan wisselen. Stabiliteit betekent dat gelijke elementen hun onderlinge volgorde behouden — handig als je bijvoorbeeld eerst op voornaam en dan op achternaam sorteert. Bubble sort en insertion sort zijn van nature stabiel (ze wisselen nooit twee gelijke elementen), selection sort is dat in zijn eenvoudige vorm niet. Bij het schoolexamen wordt vooral gevraagd of je een algoritme correct kunt naspelen, het aantal wissels of vergelijkingen kunt tellen, en kunt uitleggen waarom de complexiteit O(n2)O(n^2)O(n2) is.
(n−1)+(n−2)+⋯+1=n(n−1)2(n-1) + (n-2) + \dots + 1 = \frac{n(n-1)}{2}(n−1)+(n−2)+⋯+1=2n(n−1)​

Aantal vergelijkingen bij selection sort

De som van de vergelijkingen per ronde; de n2n^2n2-term overheerst, dus de complexiteit is O(n2)O(n^2)O(n2).

O(n2)O(n^2)O(n2)

Complexiteit van bubble, insertion en selection sort

Twee geneste lussen over nnn elementen geven een kwadratisch aantal stappen: bij dubbele invoer ongeveer vier keer zo veel werk.

Uitgewerkt voorbeeld

Bubble sort naspelen en de wissels tellen

Speel bubble sort volledig na op de rij [5, 1, 4, 2, 8] en tel het totale aantal wissels.

  1. 01Pass 1

    Vergelijk steeds twee buren: (5,1) wissel → [1,5,4,2,8]; (5,4) wissel → [1,4,5,2,8]; (5,2) wissel → [1,4,2,5,8]; (5,8) geen wissel. Drie wissels; de 8 stond al achteraan.

    [5, 1, 4, 2, 8]→[1, 4, 2, 5, 8][5,\,1,\,4,\,2,\,8] \to [1,\,4,\,2,\,5,\,8][5,1,4,2,8]→[1,4,2,5,8]
  2. 02Pass 2

    (1,4) geen wissel; (4,2) wissel → [1,2,4,5,8]; (4,5) geen wissel. Eén wissel deze ronde.

    [1, 4, 2, 5, 8]→[1, 2, 4, 5, 8][1,\,4,\,2,\,5,\,8] \to [1,\,2,\,4,\,5,\,8][1,4,2,5,8]→[1,2,4,5,8]
  3. 03Pass 3

    (1,2) en (2,4) geven geen wissel. Nul wissels: dat is het teken dat de rij gesorteerd is, dus we stoppen.

  4. 04Tel de wissels

    Tel de wissels van alle passes op. Dat komt overeen met het aantal 'inversies' (paren die verkeerd om staan) in de beginrij.

    3+1+0=43 + 1 + 0 = 43+1+0=4

Resultaat: De gesorteerde rij is [1, 2, 4, 5, 8], bereikt met 4 wissels.

Eindexamen-focus

  • Bubble, insertion of selection sort stap voor stap naspelen op een kleine rij en de tussenstanden correct opschrijven.
  • Het aantal wissels of vergelijkingen tellen en beredeneren waarom deze eenvoudige sorteringen O(n2)O(n^2)O(n2) zijn.
  • Uitleggen wat stabiliteit betekent en welke van de drie algoritmen stabiel is.

Veelgemaakte fouten

  • Bij bubble sort vergeten dat na elke pass het achterste (grootste) element al vaststaat, en dat deel toch opnieuw vergelijken.
  • Wissels en vergelijkingen door elkaar halen bij het tellen.
  • Denken dat korte, 'nette' code automatisch snel is — deze algoritmen ogen simpel maar zijn O(n2)O(n^2)O(n2).

Actieve herhaling

Speel bubble sort volledig na op de rij [3, 6, 1, 5, 2]. Schrijf de rij na elke pass op en tel het totale aantal wissels.

Actief ophalen

Haal de kernpunten op — onthul ze daarna.

Bronnen: Examenprogramma informatica (HAVO) (CvTE / Examenblad)

§ 03

Datastructuren#

●●○StandaardLPexamenblad-nl

Binaire zoekboom

Binaire zoekboom na invoegen van 8, 3, 10, 1, 6, 14, 4, 7, 13Boomdiagram, 4 paden, Gegevens: 3 → 1; 3 → 6 → 4; 3 → 6 → 7; 10 → 14 → 13631410814713
Afb. 4Afb. 4 — De zoekboom uit het uitgewerkte voorbeeld. De gemarkeerde weg 8 → 3 → 6 → 7 laat zien hoe je naar de waarde 7 zoekt: bij elke knoop kies je links (kleiner) of rechts (groter).

Kernpunten

Een datastructuur is een afgesproken manier om gegevens in het geheugen te ordenen, zó gekozen dat de bewerkingen die je vaak doet snel gaan. De eenvoudigste is de lijst of array: een rij vakjes met een vaste index 0, 1, 2, … Omdat de computer weet waar de rij begint en elk vakje even groot is, kan hij element i direct berekenen en ophalen — dat is O(1)O(1)O(1), ongeacht de lengte. Zoeken naar een wáárde (in plaats van een index) kost in een ongesorteerde lijst wél O(n)O(n)O(n), en iets ertussen invoegen is duur omdat alles moet opschuiven. Een array is dus ideaal als je vooral via de index werkt en de grootte redelijk vast is.
Twee structuren beperken bewust hóé je erbij mag: de stack en de queue. Een stack (stapel) werkt volgens LIFO — last in, first out, als een stapel borden: je legt er bovenop (push) en pakt er bovenaf (pop), dus wie het laatst kwam, gaat het eerst weg. Stacks zitten achter 'ongedaan maken'-knoppen en achter het terugkeren uit functies in een programma. Een queue (wachtrij) werkt volgens FIFO — first in, first out, als de rij bij de kassa: achteraan erbij (enqueue), vooraan eraf (dequeue), dus wie het eerst kwam, is het eerst aan de beurt. Queues gebruik je voor printtaken, netwerkpakketten en alles wat 'eerlijk op volgorde' afgehandeld moet worden. Beide bewerkingen kosten O(1)O(1)O(1).
Een boom ordent gegevens hiërarchisch. Hij begint bij één wortel (root); elke knoop (node) kan kinderen hebben, en knopen zonder kinderen heten bladeren (leaves). In een binaire boom heeft elke knoop hoogstens twee kinderen. Een binaire zóékboom (BST) legt daar een handige regel bovenop: in de linkerdeelboom van een knoop staan alleen kleinere waarden, in de rechter alleen grotere. Daardoor kun je zoeken zoals bij binair zoeken — bij elke knoop links of rechts af — wat in een gebalanceerde boom O(log⁡n)O(\log n)O(logn) kost. Afbeelding 4 toont de zoekboom die je krijgt door de getallen uit het uitgewerkte voorbeeld in te voegen. Bomen zitten onder andere in bestandsmappen, beslisbomen en de manier waarop databases hun gegevens indexeren.
Een graaf is de meest algemene structuur: een verzameling knopen (nodes) verbonden door kanten (edges). Bij een ongerichte graaf werkt een kant beide kanten op (zoals een weg tussen twee steden of een vriendschap); bij een gerichte graaf heeft elke kant een richting (zoals 'volgt op sociale media' of een eenrichtingsstraat). Grafen modelleren netwerken van elke soort: wegennetten, het internet, sociale netwerken en de afhankelijkheden tussen taken in een project. Afbeelding 5 laat zo'n kleine gerichte graaf zien. Anders dan een boom mag een graaf lussen (cykels) bevatten en hoeft er geen wortel te zijn; een boom is eigenlijk een bijzonder, lus-vrij geval van een graaf.
De hashtabel ten slotte combineert snelheid met flexibiliteit. Een hashfunctie rekent een sleutel (bijvoorbeeld een naam) om naar een getal, de index van een 'emmer' (bucket) waarin de bijbehorende waarde wordt bewaard. Omdat je zo direct naar de juiste plek springt, zijn opzoeken, toevoegen en verwijderen gemiddeld O(1)O(1)O(1) — daarom zitten hashtabellen achter woordenboeken, verzamelingen en databases. Botsingen (twee sleutels met dezelfde uitkomst) worden apart opgevangen, en in het slechtste geval zakt de prestatie naar O(n)O(n)O(n). De kunst is de juiste structuur bij je probleem te kiezen: een array voor snelle index-toegang, een stack of queue voor een strikte volgorde, een boom voor gesorteerd zoeken, een graaf voor netwerken en een hashtabel voor bliksemsnel opzoeken op sleutel.
O(1)O(1)O(1)

Array-index en hashtabel (gemiddeld)

Toegang tot element iii van een array en opzoeken in een hashtabel kosten gemiddeld constante tijd, ongeacht de grootte.

O(log⁡n)O(\log n)O(logn)

Zoeken in een gebalanceerde binaire zoekboom

Bij elke knoop kies je links of rechts, waardoor je het aantal kandidaten telkens ongeveer halveert.

Gerichte graaf

Gerichte graaf: taken en hun afhankelijkhedenGraaf, Ontwerp → Bouwen, Bouwen → Testen, Bouwen → Documentatie, Testen → Opleveren, Documentatie → OpleverenOntwerpBouwenTestenDocumentatieOpleveren
Afb. 5Afb. 5 — Een gerichte graaf (knopen + gerichte kanten) die de afhankelijkheden tussen projecttaken weergeeft: 'Opleveren' kan pas als Testen én Documentatie klaar zijn.
Uitgewerkt voorbeeld

Getallen invoegen in een binaire zoekboom

Voeg de getallen 8, 3, 10, 1, 6, 14, 4, 7, 13 in die volgorde in een lege binaire zoekboom in en beschrijf de ontstane structuur.

  1. 01Wortel

    De eerste 8 wordt de wortel. Voor elk volgend getal geldt: kleiner → naar links, groter → naar rechts, net zo lang tot je een lege plek vindt.

  2. 023 en 10

    3 < 8 → linkerkind van 8. 10 > 8 → rechterkind van 8.

  3. 031 en 6

    1 < 8 (links), 1 < 3 (links) → linkerkind van 3. 6 < 8 (links), 6 > 3 (rechts) → rechterkind van 3.

  4. 0414, 4 en 7

    14 > 8, 14 > 10 → rechterkind van 10. 4 < 8, 4 > 3, 4 < 6 → linkerkind van 6. 7 < 8, 7 > 3, 7 > 6 → rechterkind van 6.

  5. 0513

    13 > 8, 13 > 10, 13 < 14 → linkerkind van 14.

Resultaat: Je krijgt de boom van Afbeelding 4: wortel 8, met bladeren 1, 4, 7 en 13. Zoeken naar 7 volgt kort de weg 8 → 3 → 6 → 7.

Eindexamen-focus

  • De werking van een stack (LIFO) en een queue (FIFO) uitleggen en push/pop respectievelijk enqueue/dequeue correct toepassen.
  • De regel van een binaire zoekboom kennen en getallen in de juiste volgorde invoegen of opzoeken.
  • Bij een gegeven probleem beredeneren welke datastructuur (lijst, stack, queue, boom, graaf of hashtabel) het beste past.

Veelgemaakte fouten

  • Stack en queue verwisselen — LIFO (bovenop) versus FIFO (achteraan aansluiten).
  • In een binaire zoekboom kleinere waarden rechts of grotere links plaatsen.
  • Denken dat een hashtabel altijd O(1)O(1)O(1) is; bij veel botsingen kan het naar O(n)O(n)O(n) zakken.

Actieve herhaling

Voeg de getallen 6, 2, 8, 1, 4, 7, 9 in die volgorde in een lege binaire zoekboom in. Teken de boom en geef aan welke knopen bladeren zijn.

Actief ophalen

Haal de kernpunten op — onthul ze daarna.

Bronnen: Examenprogramma informatica (HAVO) (CvTE / Examenblad)

§ 04

Eindige automaten en toestandsmachines#

●●●VerdiepingLPexamenblad-nl

Deterministische eindige automaat

DFA die binaire strings accepteert die eindigen op 01Graaf, q0 (start) → q0 (start), q0 (start) → q1, q1 → q1, q1 → q2 (accept), q2 (accept) → q1, q2 (accept) → q0 (start)q0 (start)q1q2 (accept)100101
Afb. 6Afb. 6 — Een DFA die binaire strings accepteert die eindigen op 01. Vanuit elke toestand vertrekt voor elk symbool precies één pijl; de string wordt geaccepteerd als je na het laatste symbool in de gemarkeerde toestand q2 eindigt.

Kernpunten

Een eindige automaat (finite automaton) is een heel eenvoudig, abstract 'machientje' dat een rij invoersymbolen leest en op grond daarvan van toestand naar toestand springt. Je kunt het je voorstellen als een landkaart met bolletjes (toestanden) en pijlen (overgangen). Op elk moment ben je in precies één toestand; lees je een symbool, dan volg je de pijl met dat symbool naar de volgende toestand. Er is één begintoestand (waar je start) en één of meer eindtoestanden ofwel accepterende toestanden. De automaat 'onthoudt' niets meer dan zijn huidige toestand — er is geen geheugen dat bijhoudt hoe vaak of wat je precies zag — en juist die beperking maakt hem zo goed te analyseren.
De variant die je op de HAVO tegenkomt is de deterministische eindige automaat (DFA). 'Deterministisch' betekent dat er vanuit elke toestand voor elk invoersymbool precies één pijl vertrekt: gegeven de toestand en het symbool ligt de volgende toestand volledig vast, zonder keuze of toeval. Formeel beschrijf je zo'n automaat als een vijftal M=(Q,Σ,δ,q0,F)M = (Q, \Sigma, \delta, q_0, F)M=(Q,Σ,δ,q0​,F): de verzameling toestanden QQQ, het invoeralfabet Σ\SigmaΣ, de overgangsfunctie δ\deltaδ die bij (toestand, symbool) de volgende toestand geeft, de begintoestand q0q_0q0​ en de verzameling accepterende toestanden FFF. Dat oogt wiskundig, maar het is niets meer dan een nette samenvatting van het plaatje met bolletjes en pijlen.
Een string 'draai je door' de automaat om te bepalen of hij geaccepteerd of verworpen wordt. Je begint in q0q_0q0​, leest de symbolen één voor één van links naar rechts en volgt telkens de bijbehorende pijl. Is de string op, dan kijk je in welke toestand je bent geëindigd: staat die in FFF (accepterend), dan is de string geaccepteerd; zo niet, dan is hij verworpen. De verzameling van álle strings die een automaat accepteert heet de taal van die automaat. Afbeelding 6 toont een DFA die precies de binaire strings accepteert die eindigen op '01'. Merk op dat sommige toestanden een pijl naar zichzelf hebben (een zelf-lus): daarmee 'blijf je' in dezelfde toestand als een symbool niets verandert aan wat je moet onthouden.
Volg als voorbeeld de string '1101' door die automaat. Je start in q0q_0q0​; de eerste 1 houdt je in q0q_0q0​, de tweede 1 ook. De 0 brengt je naar q1q_1q1​ (je hebt net een 0 gezien, een mogelijk begin van '01'), en de laatste 1 brengt je van q1q_1q1​ naar de accepterende toestand q2q_2q2​ (je zag '01' aan het eind). De string eindigt in q2q_2q2​ en wordt dus geaccepteerd — terecht, want '1101' eindigt op '01'. De string '1010' daarentegen eindigt in q1q_1q1​ (laatste symbool 0) en wordt verworpen. Zo herken je met een handjevol toestanden een oneindig grote taal, zonder ook maar één string vooraf te hoeven opslaan.
Eindige automaten zijn niet alleen theorie: ze zitten in gereedschap dat je dagelijks gebruikt. Invoervalidatie — controleren of een postcode, e-mailadres of wachtwoord de juiste vorm heeft — is precies de vraag 'accepteert deze automaat de string?'. Reguliere expressies, waarmee programmeurs patronen in tekst beschrijven, worden intern omgezet in eindige automaten. En de lexer of scanner van een compiler, die broncode in stukjes (tokens) knipt zoals getallen, namen en operatoren, is één grote eindige automaat. Toestandsmachines sturen daarnaast verkeerslichten, liften en de menu's van apparaten aan. Overal waar een systeem 'zich in een bepaalde stand bevindt' en op gebeurtenissen reageert, is een toestandsmachine een natuurlijk model.
M=(Q,Σ,δ,q0,F)M = (Q, \Sigma, \delta, q_0, F)M=(Q,Σ,δ,q0​,F)

Een DFA als vijftal

QQQ = toestanden, Σ\SigmaΣ = invoeralfabet, δ\deltaδ = overgangsfunctie, q0q_0q0​ = begintoestand, FFF = accepterende toestanden.

δ(q1,1)=q2\delta(q_1, 1) = q_2δ(q1​,1)=q2​

Een overgang lezen

In toestand q1q_1q1​ brengt het symbool 1 je naar q2q_2q2​; zo legt de overgangsfunctie elke pijl vast.

Uitgewerkt voorbeeld

Accepteert de automaat de string 1101?

Bepaal met de DFA uit Afbeelding 6 of de string '1101' wordt geaccepteerd. Schrijf alle doorlopen toestanden op.

  1. 01Start

    Je begint in de begintoestand q0. De string is 1-1-0-1.

  2. 02Lees de eerste 1

    In q0 gaat een 1 via de zelf-lus terug naar q0.

  3. 03Lees de tweede 1

    Opnieuw houdt de 1 je in q0.

  4. 04Lees de 0

    Nu brengt de 0 je van q0 naar q1: je hebt net een 0 gezien, mogelijk het begin van '01'.

  5. 05Lees de laatste 1

    In q1 brengt de 1 je naar q2, de accepterende toestand — je zag '01' aan het eind.

    q0→q0→q0→q1→q2q_0 \to q_0 \to q_0 \to q_1 \to q_2q0​→q0​→q0​→q1​→q2​
  6. 06Controleer de eindtoestand

    De string is op en je bent in q2, dat in F zit. Dus geaccepteerd.

Resultaat: De doorlopen weg is q0 → q0 → q0 → q1 → q2; je eindigt in de accepterende toestand q2, dus '1101' wordt geaccepteerd.

Eindexamen-focus

  • Van een gegeven DFA bepalen of een concrete string wordt geaccepteerd door de toestanden stap voor stap te doorlopen.
  • De onderdelen van een eindige automaat benoemen: begintoestand, eindtoestand(en), overgangen en invoeralfabet.
  • Uitleggen wat de taal van een automaat is en een toepassing (invoervalidatie, lexen) noemen.

Veelgemaakte fouten

  • Bij een accepterende eindtoestand alleen kijken of je die onderweg passeerde, in plaats van of je er ná het laatste symbool in eindigt.
  • Een zelf-lus vergeten te volgen, waardoor je bij een herhaald symbool denkt 'vast te lopen'.
  • Denken dat een automaat de héle string moet onthouden; hij kent alleen zijn huidige toestand.

Actieve herhaling

Gegeven de DFA uit Afbeelding 6 (accepteert binaire strings die eindigen op '01'). Bepaal voor de strings '0101', '110' en '001' of ze worden geaccepteerd, door telkens de doorlopen toestanden op te schrijven.

Actief ophalen

Haal de kernpunten op — onthul ze daarna.

Bronnen: Examenprogramma informatica (HAVO) (CvTE / Examenblad)

§ 05

Formele talen en grammatica's#

●●●VerdiepingLPexamenblad-nl

Parseboom van 3 + 4 * 5

Parseboom van 3 + 4 * 5Boomdiagram, 5 paden, Gegevens: E → T → F → 3; +; T → T → F → 4; T → *; T → F → 5FTEFTFTE3+4·5
Afb. 7Afb. 7 — De parseboom van 3 + 4 5. Omdat 4 5 samen één gemarkeerde term (T) vormt, staat vast dat eerst 4 * 5 = 20 wordt berekend en pas daarna 3 + 20 = 23.

Kernpunten

Een formele taal is wiskundig veel strikter dan een gewone taal. Je begint met een alfabet Σ\SigmaΣ: een eindige verzameling symbolen, bijvoorbeeld {0, 1} of alle letters en cijfers. Een string is een eindige rij van die symbolen, en een taal is simpelweg een (vaak oneindige) verzameling van toegestane strings. Twee begrippen die je scherp moet houden zijn syntax en semantiek. Syntax gaat over de vorm: is de string volgens de regels correct opgebouwd? Semantiek gaat over de betekenis: wat stelt de string voor, wat is de waarde? '3 + + 4' is syntactisch fout; '3 + 4' is syntactisch goed en betekent semantisch 7. Een programmeertaal heeft precies zulke regels: de compiler controleert eerst de syntax en bepaalt daarna de betekenis.
Welke strings tot een taal behoren, leg je vast met een grammatica: een verzameling productieregels die beschrijven hoe je geldige strings 'maakt'. Daarin komen twee soorten symbolen voor. Terminals zijn de echte symbolen uit het alfabet die uiteindelijk in de string blijven staan (zoals cijfers, + en *). Nonterminals zijn hulpsymbolen (vaak met een hoofdletter, zoals EEE, TTT, FFF) die nog verder 'uitgewerkt' moeten worden. Een regel als E→E+TE \rightarrow E + TE→E+T zegt: een expressie EEE mag bestaan uit een expressie, een plusteken en een term. Deze schrijfwijze heet BNF (Backus-Naur-vorm), waarmee je de syntax van programmeertalen en dataformaten precies vastlegt. Het streepje ∣\mid∣ betekent 'of': F→0∣1∣⋯∣9F \rightarrow 0 \mid 1 \mid \dots \mid 9F→0∣1∣⋯∣9 zegt dat een factor precies één cijfer is.
Een afleiding (derivation) laat zien dát een string tot de taal hoort, door vanuit het startsymbool net zo lang regels toe te passen tot er alleen nog terminals staan. Elke stap vervangt één nonterminal door de rechterkant van een van zijn regels; we schrijven de stap met een dubbele pijl ⇒\Rightarrow⇒. Voor de rij '3 + 4 * 5' begin je bij EEE en werk je die stap voor stap uit tot precies die symbolen overblijven (zie het uitgewerkte voorbeeld). Slaagt dat, dan is de string syntactisch geldig. Lukt het met geen enkele regelvolgorde, dan hoort de string niet tot de taal — precies wat een compiler bedoelt met een 'syntaxfout'.
Een afleiding als platte regel is lastig te lezen; daarom tekenen we hem als een parseboom of ontleedboom. De wortel is het startsymbool, elke interne knoop is een nonterminal, en de bladeren zijn — van links naar rechts gelezen — precies de terminals van de string. De boomstructuur maakt bovendien de betekenis zichtbaar: hij groepeert wat bij elkaar hoort. In Afbeelding 7 zie je de parseboom van '3 + 4 5'. Omdat de grammatica de vermenigvuldiging 'dieper' in de boom plaatst dan de optelling, staat vast dat eerst 4 5 wordt uitgerekend en pas daarna 3 erbij: de boom codeert dus de rekenvolgorde (4 5 = 20, dan 3 + 20 = 23), en niet (3 + 4) 5 = 35.
Deze theorie is het fundament onder elke programmeertaal en elk dataformaat. Wie een taal ontwerpt, geeft eerst het alfabet en de grammatica; wie een compiler of interpreter bouwt, laat een parser met die grammatica de broncode ontleden tot een boom (de abstracte syntaxboom), waarna de betekenis wordt bepaald. Dezelfde ideeën zitten achter het lezen van HTML, JSON en XML, achter reguliere expressies, en achter de manier waarop een rekenmachine '3 + 4 * 5' correct interpreteert. Grammatica's en eindige automaten hangen bovendien samen: de eenvoudigste talen (de 'reguliere' talen) kun je zowel met een automaat herkennen als met een simpele grammatica beschrijven — twee kanten van dezelfde medaille.
E→E+T∣TE \rightarrow E + T \mid TE→E+T∣T

Regel voor een expressie

Een expressie is een expressie plus een term, of gewoon een term; de ∣\mid∣ betekent 'of'.

T→T∗F∣FT \rightarrow T * F \mid FT→T∗F∣F

Regel voor een term

Een term is een term maal een factor, of een factor; hierdoor bindt de vermenigvuldiging sterker dan de optelling.

F→0∣1∣⋯∣9F \rightarrow 0 \mid 1 \mid \dots \mid 9F→0∣1∣⋯∣9

Regel voor een factor

Een factor is in deze eenvoudige taal precies één cijfer (een terminal).

Uitgewerkt voorbeeld

3 + 4 * 5 afleiden en ontleden

Leid met de regels E→E+T∣TE \rightarrow E + T \mid TE→E+T∣T, T→T∗F∣FT \rightarrow T * F \mid FT→T∗F∣F en F→F \rightarrowF→ cijfer de string '3 + 4 * 5' af, en leg uit welke rekenvolgorde de parseboom vastlegt.

  1. 01Begin bij het startsymbool

    We starten met E en passen steeds één regel toe tot er alleen cijfers en tekens overblijven. De linker-nonterminal werken we telkens eerst uit.

    E⇒E+TE \Rightarrow E + TE⇒E+T
  2. 02Werk de linker E uit tot 3

    Kies E → T, dan T → F, dan F → 3.

    E+T⇒T+T⇒F+T⇒3+TE + T \Rightarrow T + T \Rightarrow F + T \Rightarrow 3 + TE+T⇒T+T⇒F+T⇒3+T
  3. 03Werk de rechter term uit tot 4 * 5

    De term T rechts van de + wordt 4 5: kies T → T F en werk beide factoren uit tot cijfers.

    T⇒T∗F⇒F∗F⇒4∗F⇒4∗5T \Rightarrow T * F \Rightarrow F * F \Rightarrow 4 * F \Rightarrow 4 * 5T⇒T∗F⇒F∗F⇒4∗F⇒4∗5
  4. 04Lees de betekenis af

    Omdat 4 en 5 samen onder één term T vallen, groepeert de parseboom ze: eerst 4 * 5 = 20, dan 3 + 20 = 23. De grammatica geeft de vermenigvuldiging dus voorrang.

Resultaat: De afleiding vanuit E slaagt en levert 3 + 4 * 5 op, dus de string is geldig; de parseboom (Afb. 7) legt vast dat de uitkomst 23 is, niet 35.

Eindexamen-focus

  • Terminals en nonterminals in een gegeven grammatica onderscheiden en een productieregel lezen.
  • Met gegeven regels een string afleiden vanuit het startsymbool en zo aantonen dat hij tot de taal behoort.
  • Een parseboom voor een eenvoudige expressie of zin tekenen en de bladeren als de string herkennen.

Veelgemaakte fouten

  • Terminals en nonterminals verwisselen, of vergeten dat een afleiding pas klaar is als er alleen terminals overblijven.
  • In de parseboom de rekenvolgorde negeren, waardoor 3 + 4 5 als (3 + 4) 5 wordt gelezen.
  • Syntax (vorm) en semantiek (betekenis) door elkaar halen.

Actieve herhaling

Gebruik de grammatica E→E+T∣TE \rightarrow E + T \mid TE→E+T∣T, T→T∗F∣FT \rightarrow T * F \mid FT→T∗F∣F en F→F \rightarrowF→ cijfer. Leid de string '2 * 3 + 1' af en teken de bijbehorende parseboom.

Actief ophalen

Haal de kernpunten op — onthul ze daarna.

Bronnen: Examenprogramma informatica (HAVO) (CvTE / Examenblad)

§ 06

Getalstelsels en booleaanse logica#

●●○StandaardLPexamenblad-nl

Waarheidstabel van AND, OR en XOR

Waarheidstabel van AND, OR en XORTabel met 5 kolommen en 4 rijen, Gegevens: A · B · A ∧ B · A ∨ B · A ⊕ B; 0 · 0 · 0 · 0 · 0; 0 · 1 · 0 · 1 · 1; 1 · 0 · 0 · 1 · 1; 1 · 1 · 1 · 1 · 0ABA ∧ BA ∨ BA ⊕ B00000010111001111110
Afb. 8Afb. 8 — AND is alleen waar bij twee enen; OR bij minstens één; XOR alleen als A en B verschillen.

Kernpunten

Mensen rekenen in het tientallige (decimale) stelsel, met tien cijfers 0–9 en machten van 10 als plaatswaarde. Een computer werkt met twee toestanden (stroom aan of uit) en gebruikt daarom het binaire (tweetallige) stelsel: alleen 0 en 1, met machten van 2 als plaatswaarde. In het getal 110121101_211012​ staan de posities voor 23,22,21,202^3, 2^2, 2^1, 2^023,22,21,20, dus voor 8,4,2,18, 4, 2, 18,4,2,1. Tel de posities met een 1 op en je hebt de decimale waarde: 8+4+0+1=138 + 4 + 0 + 1 = 138+4+0+1=13. Zo werkt élk stelsel — het grondtal bepaalt alleen welke machten je gebruikt. Acht bits vormen samen een byte, die dus 28=2562^8 = 25628=256 verschillende waarden (0 tot en met 255) kan voorstellen; het is de standaardbrok waarin computers geheugen tellen.
Binaire getallen worden al gauw lang en onleesbaar, daarom gebruiken informatici het hexadecimale (zestientallige) stelsel als handige korte schrijfwijze. Het heeft zestien 'cijfers': 0–9 en dan A, B, C, D, E, F voor de waarden 10 tot en met 15. Het mooie is dat vier bits precies één hexcijfer vormen (24=162^4 = 1624=16), zodat je een byte in twee hexcijfers schrijft. Zo is 1111 binair gelijk aan 15, oftewel F, en het bytepatroon 0010 1111 schrijf je als 0x2F\text{0x2F}0x2F. Omrekenen van hex naar decimaal gaat weer met plaatswaarden, nu machten van 16: 0x2F=2⋅16+15=47\text{0x2F} = 2 \cdot 16 + 15 = 470x2F=2⋅16+15=47. Je ziet hexadecimaal overal waar bits een rol spelen: kleurcodes (zoals #FF8800), geheugenadressen en foutcodes.
Naast getallen rekent een computer met waarheidswaarden: waar (1) en onwaar (0). De booleaanse logica kent drie basisoperatoren. AND (∧\land∧) is alleen waar als béíde ingangen waar zijn; OR (∨\lor∨) is waar als mínstens één ingang waar is; NOT (A‾\overline{A}A) keert een waarde om. Een vierde, veelgebruikte operator is XOR (⊕\oplus⊕, de 'exclusieve of'): waar als de ingangen verschíllen. Deze operatoren zitten letterlijk in de hardware als logische poorten, en in software in elke 'als … en/of … dan'-voorwaarde. Afbeelding 8 vat AND, OR en XOR samen in één waarheidstabel. Let op het verschil tussen OR (ook waar als beide waar zijn) en XOR (juist níét waar als beide waar zijn).
Om een samengestelde booleaanse expressie te doorgronden maak je een waarheidstabel: je zet alle mogelijke combinaties van de ingangen in de rijen en rekent de expressie kolom voor kolom uit. Bij nnn ingangen zijn er 2n2^n2n rijen — twee variabelen geven 4 rijen, drie variabelen 8. Handig is om eerst tussenkolommen te maken voor de deeluitdrukkingen. Voor A∧(B‾∨C)A \land (\overline{B} \lor C)A∧(B∨C) bereken je bijvoorbeeld eerst B‾\overline{B}B, dan B‾∨C\overline{B} \lor CB∨C, en pas daarna de hele AND. Zo houd je overzicht en maak je minder fouten. Het uitgewerkte voorbeeld en Afbeelding 9 lopen deze tabel helemaal door. Twee expressies zijn logisch gelijkwaardig als hun resultaatkolommen precies gelijk zijn.
Voor booleaanse expressies gelden rekenregels, net als in de gewone algebra. De bekendste zijn de wetten van De Morgan, die vertellen hoe een NOT over een AND of OR 'heen valt' en daarbij de operator omklapt: A∧B‾=A‾∨B‾\overline{A \land B} = \overline{A} \lor \overline{B}A∧B=A∨B en A∨B‾=A‾∧B‾\overline{A \lor B} = \overline{A} \land \overline{B}A∨B=A∧B. In woorden: 'niet (A én B)' is hetzelfde als 'niet A óf niet B'. Je kunt zulke wetten bewijzen door beide kanten in een waarheidstabel te zetten en te zien dat de resultaatkolommen gelijk zijn. Verder gelden onder meer A∧0=0A \land 0 = 0A∧0=0, A∨1=1A \lor 1 = 1A∨1=1 en A∧A‾=0A \land \overline{A} = 0A∧A=0. Met deze regels vereenvoudig je logische schakelingen en voorwaarden, wat kan schelen in hardware en in de leesbaarheid van code.
11012=1⋅23+1⋅22+0⋅21+1⋅20=13101101_2 = 1\cdot 2^3 + 1\cdot 2^2 + 0\cdot 2^1 + 1\cdot 2^0 = 13_{10}11012​=1⋅23+1⋅22+0⋅21+1⋅20=1310​

Binair naar decimaal met plaatswaarden

Tel de machten van 2 op de posities met een 1 op: 8+4+1=138 + 4 + 1 = 138+4+1=13.

1310=D1613_{10} = \text{D}_{16}1310​=D16​

Decimaal naar hexadecimaal

13 is kleiner dan 16 en komt overeen met het hexcijfer D.

A∧B‾=A‾∨B‾\overline{A \land B} = \overline{A} \lor \overline{B}A∧B=A∨B

Wet van De Morgan

Een NOT over een AND wordt een OR van de losse NOT's — de operator klapt om.

Waarheidstabel van A ∧ (¬B ∨ C)

Waarheidstabel van A ∧ (¬B ∨ C)Tabel met 6 kolommen en 8 rijen, Gegevens: A · B · C · ¬B · ¬B ∨ C · A ∧ (¬B ∨ C); 0 · 0 · 0 · 1 · 1 · 0; 0 · 0 · 1 · 1 · 1 · 0; 0 · 1 · 0 · 0 · 0 · 0; 0 · 1 · 1 · 0 · 1 · 0; 1 · 0 · 0 · 1 · 1 · 1; 1 · 0 · 1 · 1 · 1 · 1; 1 · 1 · 0 · 0 · 0 · 0; 1 · 1 · 1 · 0 · 1 · 1, gemarkeerde cel: 1ABC¬B¬B ∨ CA ∧ (¬B ∨ C)000110001110010000011010100111101111110000111011
Afb. 9Afb. 9 — Stap voor stap: eerst ¬B, dan ¬B ∨ C, dan de hele AND. De expressie is alleen waar in de rijen (1,0,0), (1,0,1) en (1,1,1); de eerste daarvan is gemarkeerd.
Uitgewerkt voorbeeld

1101 omrekenen en een waarheidstabel invullen

Reken 110121101_211012​ om naar decimaal en hexadecimaal, en vul de waarheidstabel van A∧(B‾∨C)A \land (\overline{B} \lor C)A∧(B∨C) in.

  1. 01Binair naar decimaal

    Schrijf de plaatswaarden 8, 4, 2, 1 onder de bits en tel de posities met een 1 op.

    11012=8+4+0+1=13101101_2 = 8 + 4 + 0 + 1 = 13_{10}11012​=8+4+0+1=1310​
  2. 02Decimaal naar hexadecimaal

    13 past in één hexcijfer: de waarde 13 heet in hex D. Dus 1101 binair is 0xD.

    1310=D1613_{10} = \text{D}_{16}1310​=D16​
  3. 03Zet de tabel op

    Drie variabelen geven 2³ = 8 rijen. Maak eerst tussenkolommen voor ¬B en ¬B ∨ C, en reken dan de AND met A uit.

  4. 04Reken de rijen uit

    De expressie is alleen waar als A = 1 én (¬B ∨ C) waar is. Dat gebeurt in de rijen (A,B,C) = (1,0,0), (1,0,1) en (1,1,1); in alle andere rijen is de uitkomst 0.

    A∧(B‾∨C)A \land (\overline{B} \lor C)A∧(B∨C)

Resultaat: Er geldt 11012=1310=0xD1101_2 = 13_{10} = \text{0xD}11012​=1310​=0xD; de expressie A∧(B‾∨C)A \land (\overline{B} \lor C)A∧(B∨C) is waar in 3 van de 8 rijen (zie Afb. 9).

Eindexamen-focus

  • Getallen omrekenen tussen binair, decimaal en hexadecimaal met behulp van de plaatswaarden.
  • Een waarheidstabel opstellen en een samengestelde expressie met AND, OR, NOT en XOR rij voor rij evalueren.
  • De wetten van De Morgan toepassen of met een waarheidstabel aantonen dat twee expressies gelijkwaardig zijn.

Veelgemaakte fouten

  • Bij binair naar decimaal de plaatswaarden verkeerd om zetten (van rechts naar links begint het bij 202^020).
  • OR ('minstens één') verwarren met XOR ('precies één / verschillend').
  • Bij De Morgan de operator niet omklappen: A∧B‾\overline{A \land B}A∧B wordt A‾∨B‾\overline{A} \lor \overline{B}A∨B, niet A‾∧B‾\overline{A} \land \overline{B}A∧B.

Actieve herhaling

Reken 1011012101101_21011012​ om naar decimaal en naar hexadecimaal, en stel de volledige waarheidstabel op van de expressie (A∨B)∧C‾(A \lor B) \land \overline{C}(A∨B)∧C.

Actief ophalen

Haal de kernpunten op — onthul ze daarna.

Bronnen: Examenprogramma informatica (HAVO) (CvTE / Examenblad)

Inhoud

Sectie -- / 06

    • 01Algoritmen en complexiteit○
    • 02Sorteeralgoritmen◐
    • 03Datastructuren◐
    • 04Eindige automaten en toestandsmachines●
    • 05Formele talen en grammatica's●
    • 06Getalstelsels en booleaanse logica◐

0/6 Gelezen

Van samenvatting naar oefening

Domein B: Grondslagen

Verstevig dit onderwerp met vragen uit de vragenbank.

~33
min
4
Vaardigheden
Oefenen

Referenties en bronnen

Bronnen

CvTE / Examenblad

  • Examenprogramma informatica (HAVO)

Vorig onderwerp

Domein A: Vaardigheden

Volgend onderwerp

Domein C: Informatie

EuraStudy·Samenvattingen T·02·MMXXVI

Ga verder met het volgende onderwerp — je leerpad blijft bewaard.