stakke og LIFO-strukturer: implementerings-og brugssager

med disse vigtige metoder forklaret, lad os se på den endelige implementering af vores Stack-klasse:

push-og pop-metoderne vises nøjagtigt som vi forventer (linjer13–32). Vi kan bruge vores push-metode til at oprette en brugerdefineret initialisator med nogle variadiske værdier (linjer 7-11). Derudover kan vi tjekke for en tom stak ved at kontrollere, om vores rootNode har en værdi (linjer 34-36) og har en grundlæggende udskrivningsmetode, der gentager gennem vores liste, så længe den er i stand til at få adgang til noder gennem den næste egenskab (linjer 38-44).

en grundlæggende test af vores stack-funktionalitet ser sådan ud:

at vide, hvordan man implementerer en stak, er en ting, men endnu vigtigere er at genkende situationer, hvor en stak er velegnet. I dette næste afsnit vil vi se på tre sådanne tilfælde.

Use Case 1: Omvendt rækkefølge

fordi rækkefølgen af en stak er fast, kan omvendt rækkefølge opnås meget let ved at poppe elementer fra en stak og straks på en anden. Ingen rode rundt med bytte indekser!

Use Case 2: Test symmetri

en anden god use case for stakke tester symmetri. I eksemplet nedenfor tester vi en række beslag for at sikre, at hver lukkebeslag er den korrekte modstykke til en tidligere åbningsbeslag.

vi starter med at kontrollere, at tegntællingen er delelig med to, da et ulige antal tegn straks ville være asymmetrisk (linje 6). Dernæst kontrollerer vi, at vi har gyldigt input ved at definere et tegnsæt med ulovlige tegn og derefter kontrollere, at vores inputstreng har en nul række ulovlige tegn (linjer 7-8). For at kontrollere, at vores luknings-og åbningsbeslag er en kamp, sætter vi dem i en ordbog som nøgleværdipar (linje 10). I andre situationer kan du muligvis beregne den inverse værdi uden at skulle gemme par i en ordbog. Så har vi vores stak (linje 11). Formålet med vores stak er i dette tilfælde at gemme åbningsbeslag. Når vi gentager gennem vores streng, kan vi kontrollere, om vores karakter er en åbningsbeslag ved at teste, om det er en nøgle i vores ordbog. Hvis det er, skubber vi det på vores stak. Når vi først har fundet vores første lukkede beslag, ved vi, at vi arbejder gennem anden halvdel af vores mønster, Så vi sætter vores firsthalv boolske til falsk (linje 12). Hvis vi finder flere åbningsbeslag efter dette punkt, kan vi kontrollere boolean og angive en mislykket test. For hver lukkebeslag, vi springer den sidste åbningsbeslag ud og kontrollerer, om de er et korrekt nøgleværdipar. Endnu en gang behøver vi kun at gentage gennem strengen en gang, så vi får meget værdi ud af en lineær algoritme.

brug sag 3: fortrydelse af kommandoer

endelig bruger vi en stak sammen med kommandomønsteret til at oprette en fortryd-historie. For at starte, lad os se på et simpelt bankkontoobjekt. Det har en balance og en overtræk grænse og nogle enkle metoder til deponering og tilbagetrækning af midler:

i stedet for at kalde indbetalings-og udbetalingsmetoderne direkte, kan vi gemme de relevante oplysninger i en kommando. I uddraget nedenfor specificerer vi, hvilken slags handling vi vil udføre med en enum-ejendom (depositum eller tilbagetrækning) og et beløb . Vi gemmer også en boolsk for at angive, om kommandoen kunne udføres (linjer 4-11). Bemærk, at hvis tilbagetrækningsanmodningen overstiger overtræksgrænsen, sker der intet med bankkontoen, og den efterfulgte boolske forbliver falsk, ellers bliver det sandt, når kommandoen er afsluttet (linjer 18-26). Vi har to metoder til at ringe eller fortryde kommandoen, der hver tager en bankkonto som et argument (linjer 18 & 28). Disse metoder tager bankkontoen og kalder dens instansmetoder, som vi så i det foregående uddrag.

når vi går tilbage til bankkontoen, kan vi nu introducere vores commandStack-ejendom, som er initialiseret med vores BankAccountType (linje 47). Vi markerer vores indbetalings-og udbetalingsmetoder som fileprivate, så de kun kan tilgås af vores BankAccountCommand (linjer 62 & 66). Nu har vi to eksponerede metoder: proces (kommando:) og undoLastCommand (). Den første accepterer en kommando som input, udfører den med bankkontoen som input og skubber derefter kommandoen på stakken. I mellemtiden undoLastCommand metode, popper den sidste kommando fra stakken og udfører en fortryd (linjer 51-60).

dette er et meget simpelt mønster, og en, der er meget kraftfuld. De mulige applikationer er uendelige og giver en tilfredsstillende brugeroplevelse.

lad os nu se mønsteret i aktion:

Pak

i denne artikel udforskede vi konceptet med en stak og LIFO-adfærd. Vi implementerede vores egen stak ved hjælp af en dobbelt sammenkædet liste og demonstrerede, hvordan den tildeler og deallokerer hukommelse, når størrelsen på stakken ændres. Vi kiggede også på tre almindelige brugssager til stakke: reversering, test af symmetri og fortrydelse. Hver af disse tre situationer kommer op utallige gange i virkelige verdensprojekter. Jeg håber, at du vil tænke på en stak som en passende struktur til håndtering af disse behov. Som altid, tak fordi du læste!

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.

More: