Strengtype

I datalogi er en strengtype ( engelsk  streng "tråd, streng") en datatype, hvis værdier er en vilkårlig sekvens (streng) af alfabettegn . Hver variabel af denne type ( strengvariabel ) kan repræsenteres af et fast antal bytes eller have en vilkårlig længde.

Hukommelsesrepræsentation

Nogle programmeringssprog pålægger begrænsninger på den maksimale længde af en streng, men de fleste sprog har ikke sådanne begrænsninger. Når du bruger Unicode, kan hvert tegn af strengtypen kræve to eller endda fire bytes for at repræsentere det.

Hovedproblemerne i maskinrepræsentationen af ​​strengtypen er:

Der er to grundlæggende forskellige tilgange til at repræsentere strenge i computerhukommelsen.

Tegnmatrixrepræsentation

I denne tilgang er strenge repræsenteret af en række tegn ; størrelsen af ​​arrayet er gemt i et separat (service) område. Fra navnet på Pascal -sproget , hvor denne metode først blev implementeret, kaldes denne metode Pascal-strenge .

En lidt optimeret version af denne metode er den såkaldte. c-addr u- format (fra engelsk  tegnjusteret adresse + usigneret nummer ) brugt i Forth . I modsætning til Pascal-strenge er størrelsen af ​​arrayet her ikke gemt sammen med strengdataene, men er en del af markøren til strengen.

Fordele
  • programmet på hvert tidspunkt indeholder information om størrelsen af ​​strengen, så operationerne med at tilføje tegn til slutningen, kopiere strengen og faktisk få strengstørrelsen udføres ret hurtigt;
  • strengen kan indeholde alle data;
  • det er muligt på programniveau at overvåge udgangen fra linjegrænserne under dens behandling;
  • det er muligt hurtigt at udføre en handling som "at tage det N. tegn fra slutningen af ​​strengen".
Ulemper
  • problemer med lagring og behandling af tegn af vilkårlig længde;
  • stigning i omkostningerne ved lagring af strenge - værdien af ​​"strenglængde" optager også plads og kan i tilfælde af et stort antal strenge af lille størrelse øge algoritmens krav til RAM betydeligt;
  • maksimal linjestørrelsesgrænse. I moderne programmeringssprog er denne begrænsning mere teoretisk, da størrelsen af ​​en streng typisk er gemt i et 32-bit felt, hvilket giver en maksimal strengstørrelse på 4.294.967.295 bytes (4 gigabyte);
  • ved brug af et alfabet med variabel tegnstørrelse (for eksempel UTF-8 ), gemmer størrelsen ikke antallet af tegn, men størrelsen af ​​strengen i bytes, så antallet af tegn skal tælles separat.

Afsluttende byte metode

Den anden metode er at bruge "termineringsbyten" [1] [2] . En af de mulige værdier for tegnene i alfabetet (normalt et tegn med kode 0) vælges som terminator af strengen, og strengen lagres som en sekvens af bytes fra start til slut. Der er systemer, hvor byten 0xFF (255) eller tegnkoden "$" bruges som tegn på slutningen af ​​linjen, ikke tegnet 0.

Metoden har tre navne - ASCIIZ (eller asciz, ASCII-tegn med en null-terminerende byte), C-strenge (metoden er mest udbredt i C -sproget ) og nultermineret strengmetode .

Fordele
  • fraværet af yderligere serviceinformation om linjen (undtagen den endelige byte);
  • evnen til at repræsentere en streng uden at oprette en separat datatype;
  • ingen grænse for den maksimale linjestørrelse;
  • økonomisk brug af hukommelse;
  • let at få strengsuffikset;
  • let at overføre strenge til funktioner (en pointer til det første tegn sendes);
Ulemper
  • lang udførelse af operationer for at opnå længden og sammenkædningen af ​​strenge;
  • mangel på midler til at kontrollere outputtet af linjen, i tilfælde af skade på den endelige byte, muligheden for at beskadige store områder af hukommelsen, hvilket kan føre til uforudsigelige konsekvenser - tab af data, nedbrud af programmet og endda hele systemet;
  • manglende evne til at bruge det afsluttende byte-tegn som et strengelement.
  • manglende evne til at bruge nogle kodninger med en tegnstørrelse på flere bytes (for eksempel UTF-16), da i mange sådanne tegn, for eksempel  (0x0100), er en af ​​bytes nul (samtidigt er UTF- 8-kodning er fri for denne ulempe).

Ved at bruge begge metoder

På sprog som for eksempel Oberon placeres en streng i en række tegn af en vis længde, og dens slutning er angivet med et nultegn. Som standard er hele arrayet fyldt med nul-tegn. Denne metode giver dig mulighed for at kombinere mange af fordelene ved begge tilgange, samt undgå de fleste af deres ulemper.

Listevisning

Sprogene ​​Erlang [3] , Haskell [4] , Prolog [5] bruger en liste over tegn til strengtypen . Denne metode gør sproget mere "teoretisk elegant" ved at respektere ortogonalitet i typesystemet , men medfører en betydelig præstationsstraf.

Implementering i programmeringssprog

  • De første programmeringssprog havde slet ikke en strengtype; programmøren skulle bygge funktioner til at arbejde med strenge af en eller anden type.
  • C bruger null- terminerede strenge med fuld manuel kontrol af programmøren.
  • I standard Pascal ser en streng ud som en matrix på 256 bytes; den første byte lagrede længden af ​​strengen, resten lagrede dens krop. Strenglængden må således ikke overstige 255 tegn. Borland Pascal 7.0 introducerede også "a la C " linjer, tilsyneladende på grund af det faktum, at Windows var inkluderet blandt de understøttede platforme .
  • I Object Pascal og C++ STL er en streng en "sort boks", hvor hukommelsesallokering/deallokering sker automatisk - uden deltagelse af programmøren . Når en streng oprettes, allokeres hukommelse automatisk; så snart der ikke er nogen reference tilbage til strengen, returneres hukommelsen til systemet. Fordelen ved denne metode er, at programmøren ikke behøver at tænke på, hvordan strenge fungerer. På den anden side har programmøren utilstrækkelig kontrol over driften af ​​programmet i hastighedskritiske områder; det er også svært at overføre sådanne strenge som en parameter til en DLL . Objekt Pascal sørger også automatisk for, at der er et tegn med kode 0 i slutningen af ​​strengen. Derfor, hvis funktionen kræver en null-termineret streng som input , skal du blot skrive eller (for Pascal), (for Builder ) /STL) for at konvertere.PAnsiChar(строковая_переменная)PWideChar(строковая_переменная)переменная.c_str()
  • I C# og andre skrald-samlede sprog er en streng et uforanderligt objekt; hvis strengen skal ændres, oprettes et andet objekt. Denne metode er langsom og spilder en masse midlertidig hukommelse, men passer godt sammen med konceptet med affaldsindsamling. Fordelen ved denne metode er, at opgaven er hurtig og uden duplikerede rækker. Der er også en vis manuel kontrol over konstruktionen af ​​strenge (i Java , for eksempel gennem klasser StringBuffer и StringBuilder) - dette giver dig mulighed for at reducere antallet af hukommelsestildelinger og udgivelser og dermed øge hastigheden.
    • På nogle sprog (for eksempel Standard ML ) er der desuden et ekstra modul for at give endnu større effektivitet - "substring" (SubString). Dens brug giver dig mulighed for at udføre operationer på strenge uden at kopiere deres kroppe ved at manipulere indekserne for begyndelsen og slutningen af ​​understrengen; fysisk kopiering sker kun, når det er nødvendigt at konvertere understrenge til strenge.

Operationer

Grundlæggende strengoperationer
  • få et tegn efter positionsnummer (indeks) - på de fleste sprog er dette en triviel operation;
  • sammenkædning (forbindelse) af strenge.
Afledte operationer Operationer ved behandling af strenge som lister
  • vikling ;
  • kortlægning fra en liste til en anden;
  • filtrering af listen efter kriterier.
Mere komplekse operationer
  • finde den minimale superstreng indeholdende alle de specificerede strenge;
  • søg i to rækker af strenge efter matchende sekvenser ( plagiatproblem ) .
Mulige opgaver til naturlige sprogstrenge

Tegnrepræsentation af en streng

Indtil for nylig var ét tegn altid kodet som én byte (8 binære bit; der blev også brugt kodninger med 7 bit pr. tegn), hvilket gjorde det muligt at repræsentere 256 (128 med en syv-bit kodning) mulige værdier. Men for en fuld repræsentation af tegnene i alfabeterne på flere sprog (flersprogede dokumenter, typografiske tegn - flere typer citater , bindestreger , flere typer mellemrum og til at skrive tekster på hieroglyfiske sprog - kinesisk , japansk og koreansk ) 256 tegn er ikke nok. Der er flere metoder til at løse dette problem:

  • Sprogskifte med kontrolkoder. Metoden er ikke standardiseret og fratager teksten uafhængighed (det vil sige, en sekvens af tegn uden en kontrolkode i begyndelsen mister sin betydning); brugt i nogle tidlige Russificeringer af ZX-Spectrum og BK .
  • Brug af to eller flere bytes til at repræsentere hvert tegn ( UTF-16 , UTF-32 ). Den største ulempe ved denne metode er tabet af kompatibilitet med tidligere tekstbiblioteker, når en streng repræsenteres som ASCIIZ. For eksempel skal slutningen af ​​en streng ikke længere betragtes som en byte med værdien 0, men to eller fire på hinanden følgende nulbytes, mens en enkelt byte "0" kan forekomme i midten af ​​en streng, hvilket forvirrer biblioteket.
  • Brug af en kodning med variabel tegnstørrelse. For eksempel i UTF-8 er nogle tegn repræsenteret af én byte, nogle af to, tre eller fire. Denne metode giver dig mulighed for at bevare delvis kompatibilitet med gamle biblioteker (der er ingen 0-tegn inde i strengen, og derfor kan 0 bruges som et tegn på slutningen af ​​strengen), men fører til, at det er umuligt at adressere et tegn direkte i hukommelsen ved at dets positionsnummer i strengen.

Leksikalsk analyse

For at kontrollere overensstemmelsen af ​​alle ordformer under leksikalsk (semantisk) analyse, bruges symbolske lighedsmål:

Se også

Noter

  1. Den dyreste en-byte fejl - ACM-kø . Hentet 17. september 2016. Arkiveret fra originalen 19. september 2016.
  2. Joel om software - Tilbage til det grundlæggende . Hentet 17. september 2016. Arkiveret fra originalen 16. september 2016.
  3. Simon St. Laurent. Introduktion til Erlang . - O'Reilly Media, Inc., 2013. - S.  62 . — 185 sider. - ISBN 978-1-449-33176-4 .
  4. Bryan O'Sullivan, Don Stewart, John Goerzen, Real World Haskell. Appendiks B. Tegn, strenge og escape-regler Arkiveret 26. januar 2012 på Wayback Machine
  5. SWI-Prolog Manual: 5.2.2 Repræsenterer tekst: strenge, atomer og kodelister Arkiveret 17. juli 2014 på Wayback Machine