tus0.gif (69 bytes)
 

ELEKTRONINĖS KNYGOS

tus0.gif (69 bytes)

Gintautas GRIGAS
PROGRAMAVIMAS PASKALIU

9. TEKSTAI

Su tekstais dirbame daugiau, negu su skaičiais. Bet veiksmai su tekstais paprastesni. Todėl ir tekstinių uždavinių programavimui skiriame mažiau dėmesio – tik vieną šios knygos skyrių.

Su tekstų dorojimu susiduriame, kai reikia tvarkyti tekstus. Tai vertimo iš vienos kalbos į kitą, redagavimo, kalbos analizės uždaviniai. Programa taip pat tekstas. Todėl programos analizės bei transliavimo uždaviniuose reikia atlikti daug veiksmų su tekstais. Tai gana sudėtingos programos ir mes jų nenagrinėsime. Keletą paprastesnių programų transliavimo programų galima rasti knygose [2, 3]. Čia pateiksime tik elementarius algoritmus su tekstais.

9.1. Simboliai

Pats mažiausias ir nebedalomas teksto elementas yra simbolis. Jis priklauso simbolių tipui char. Simbolių tipą galima laikyti specialia vardinio duomenų tipo rūšimi ir taikyti visas vardinio duomenų tipo operacijas. Iš tikrųjų taip ir yra.

Su simboliais atliekamos tos pačios operacijos ir funkcijos, kaip ir su vardinio duomenų tipo reikšmėmis: <, <=, =, <>, >, >=, succ, pred. Be to Paskalio kalboje vartojamos standartinės funkcijos, būdingos simbolių tipui.

Funkcijos ord(s) argumentas s yra simbolis, bendru atveju – simbolių tipo reiškinys, o rezultatas yra sveikųjų skaičių atkarpos 0..255 tipo. Tai simbolio s kodas kompiuteryje.

Funkcija chr(i) atlieka atvirkščią veiksmą, negu ord – skaičių iš minėto intervalo paverčia simboliu.

Kadangi funkcijos ord ir chr yra atvirkštinės, tai jų parametrai ir reikšmės susijusios taip:

chr(ord(s)) = s,
ord(chr(i)) = i.

Daugelio operacijų su simboliais rezultatas priklauso nuo simbolių surikiavimo į eilę. O jo neapibrėžia nei Paskalio kalba, nei jo dialektai. Tiesiog pasakoma, kad simboliai surikiuoti pagal jų kodus kompiuteryje. Reikalaujama tik, kad skaitmenų simboliai būtų surikiuoti pagal eilė '0', '1', ... , '9' ir jų kodai eitų ištisai, t.y, tarp skaitmenų negali būti jokių kitų simbolių, išskyrus skaitmenis.

Simbolių kodai kompiuteryje priklauso nuo to, kokia (kokios valstybės) kodavimo lentelė tuo metu veikia kompiuteryje. Dėl to iš operacijų su simboliais mažai naudos.

Funkciją ord patogu vartoti, kai reikia skaitmens simbolį paversti vienaženkliu sveikuoju skaičiumi. Jeigu funkcijos argumento s reikšmė yra skaitmens simbolis, tai norint šį simbolį pakeisti skaičiumi i, rašome:

i := ord(s) - ord(’0’)

Pagal šį sakinį visada simbolis bus pakeistas jį atitinkančiu vienženkliu skaičiumi, kad ir kaip kompiuteryje būtų koduojami simboliai, nes skaitmenų simboliai eina iš eilės be tarpų visuose kompiuteriuose. Pavyzdžiui, personaliniuose kompiuteriuose naudojamoje ASCII kodų lentelėje nulio kodas yra 48, o trejeto kodas yra 51. Todėl gausime:

ord('3') - ord(’0’) => 3.

Dideliuose kompiuteriuose naudojamame EBCDIC kodų lentelėje nulio kodas yra 240, o trejeto kodas yra 243. Todėl ir čia minėto reiškinio reikšmė bus ta pati – skaičius 3.

Jeigu tiesiogiai į reiškinį rašytume kodą, pavyzdžiui simbolio pakeitimą vienaženkliu skaičiumi užrašytume taip:

i := ord(s) - 48

tai toks veiksmas nebūtų universalus, nes jis tiktų tik vienai (personalinių) kompiuterių klasei. Be to ir skaityti tokį užrašą būtų sunkiau, nes norint jį suvokti reikia žinoti, kas skaičius 48 reiškia nulio kodą. Dėl to simbolių kodai vartotini tik tada, kai atliekami veiksmai su kodais, pavyzdžiui perkodavimo algoritmuose. Kitose programose, kai dirbama su tikrais (literatūriniais) tekstais, tiesioginio simbolių kodų panaudojimo reikia vengti.

1 pavyzdys. Skaitymo procedūra read gali skaityti realiuosius skaičius, kuriuose trupmeninė dalis nuo sveikosios skiriama tašku. Lietuvoje, o taip pat daugelyje Europos valstybių priimta trupmeninę skaičiaus dalį nuo sveikosios skirti kableliu. Parašysime procedūrą šitaip klaviatūra surinktiems skaičiams skaityti. Laikysime, kad skaičiai užrašyti vien dešimtainėmis trupmenomis, t.y., rodyklinis jų užrašas nevartojamas.

procedure readreal (var byla: text; var r: real);
   var s: char;                            { skaitomas simbolis }
         d: real;                             { trupmenos daugiklis }
         neigiamas : boolean;
begin
  
r := 0; d := 1; neigiamas := false;
   read(byla, s);
   while s = ' ' do                       { praleidžiami tarpai }
       read(byla, s);
   if s = '-' then begin
                         
neigiamas := true;
                          read(byla, s)
                       end
               else if
s = ’+’
                         then read(byla, s);
   while (s in ['0'..'9']) and not eof(byla) do
      begin
        
r := r*10 + (ord(s) - ord('0'));
         read(byla, s)
      end;
   if s = ',' then                           { skaičius turi trupmeninę dalį }
      begin
        
read(byla, s); { praleidžiamas kablelis }
         while s in ['0'..'9'] do
            begin
               
d := d*0.1;
                r := r + (ord(s)-ord('0'))*d;
                read(byla, s)
            end
      end
;
   if neigiamas then r := -r
end;

Panašiai skaičius iš simbolių formuoja ir standartinė skaitymo procedūra read. Apskritai, visos tekstinės bylos yra sudarytos vien iš simbolių. Tiktai skaitymo procedūros tuo atveju kai jų parametras yra skaičius iš bylos skaito visus skaičių sudarančius simbolius (iki aptinka simbolį, kuris nebepriklauso skaičiui) ir iš jį suformuoja sveikąjį arba realųjį skaičių, pagal kintamojo tipą. Deja, pastarosios galimybės neturi programuotojo sudaromos procedūros – jose reikia nurodyti parametrų skaičių ir kiekvieno jų tipą.

Simbolio skaitymas procedūra read yra pats paprasčiausias: perskaitomas vienas simbolis, tas, kurį rodo bylos žymeklis, žymeklis paslenka per vieną poziciją į dešinę ir ima rodyti kitą simbolį byloje. Jokių išimčių nėra, nes visi simboliai, ar tai būtų tarpas, ar apostrofas, ar bet kuris kitas simbolis. Tarpas yra lygiavertis simbolis. Apostrofas tekstinėje byloje taip pat yra apostrofas, nes bylą sudaro vien simboliai ir nėra nuo ko jų atskirti. Tuo tarpu programos tekste tik dalis simbolių naudojami kaip simbolinio tipo reikšmės. Todėl ten reikalingi specialūs simboliai, kurie juos atskirtų nuo kito programos teksto. Šiam tikslui ir yra vartojami apostrofai.

Taigi, simbolinis duomenų tipas yra pats svarbiausias duomenų saugojimo diske tipas.

Teoriškai pakaktų tokių procedūrų, kurios gali skaityti ir rašyti tik simbolio tipo duomenis, nes visų kitų tipų duomenys kompiuterio išorėje vaizduojami simboliais. Tačiau praktiškai tai būtų nepatogu, nes reikėtų detaliai programuoti duomenų skaitymo ir rašymo veiksmus. Dėl to šie veiksmai įjungti į procedūras read ir write. Kai šių procedūrų parametrai yra kitokio tipo (negu tipo char), tai skaitomi simboliai automatiškai keičiami to tipo reikšmėmis arba to tipo reikšmės keičiamos rašomais (spausdinamais) simboliais.

Grįžkime prie simbolių kodavimo. Aiškinome, kokie pavojai slypi, kai programoje tiesiogiai naudojamos simbolių kodų reikšmės. Betgi kompiuterio atmintinėje saugomi simbolių kodai, o ne patys simboliai. Todėl gali kilti klausimas, ar tos simbolių eilutės, kurias įterpiame į rašymo sakinius, bus matomos vaizduoklio ekrane arba išspausdintos teisingai?

Kompiuteris rodys ekrane arba išspausdins lygiai tokias simbolių eilutes, kokias matome parašytas programoje. Jeigu programos tekstą norėsime perkelti į kompiuterį, kuriame naudojama kita kodavimo lentelė, tai tada programą reikės perkoduoti lygiai taip, kaip perkoduojami visi kiti tekstai perkeliami tekstai. Kai programos tekstas bus perkoduotas, naujas kompiuteris rodys teisingus simbolius programos tekste, o taip pat tos programos išspausdintuose arba ekrane rodomuose rezultatuose.

Nuo kodavimo nepriklauso lyginimo = ir <> , o taip pat priklausomybės aibei in operacijų rezultatai.

Uždaviniai

9.1.1. Kodėl procedūroje readreal nėra kreipinių į procedūras assign ir reset.

9.1.2. Parašykite dvi funkcijas: vieną, pakeičiančią simbolį vienaženkliu skaičiumi, kitą –
         vienaženklį neneigiamą skaičių simboliu. Prieš tai aprašykite du atkarpos: sveikųjų
         skaičių ir simbolių.

9.1.3. Įsivaizduokime, kad skaitymo procedūra read gali skaityti tik char tipo duomenis.
         Sudarykite procedūrą vienam sveikajam skaičiui skaityti.

Praktikos darbai

9.1.1. Realiojo skaičiaus formavimas iš simbolių. Papildykite 1 pavyzdžio procedūrą taip, kad ji galėtų skaityti ir skaičius, užrašytus rodikliniu pavidalu.

9.1.2. Realiojo skaičiaus pavertimas simbolių seka. Sudarykite realiųjų skaičių rašymo procedūrą tokią, kad trupmeninė skaičiaus dalis būtų skiriama kableliu. Procedūra turi turėti du variantus: vieną skaičiui rašyti dešimtainės trupmenos pavidalu (ji turi tris parametrus: rašomą skaičių ir du skaičius, kuriais nurodomas formatas) ir rodikliniu pavidalu (turi du parametrus – skaičių ir formatą).

9.2. Simbolių eilutės

Simbolis yra per mažas teksto elementas. Todėl vartojami didesni. Paskalio standarte stambesni teksto elementai gaunami panaudojant pakuotus simbolių masyvus (packed array). Turbo Paskalyje ir kituose Paskalio dialektuose vartojamos simbolių eilutės. Su simbolių eilučių kintamaisiais ir konstantomis jau esame susipažinę. Dabar panagrinėsime, eilučių tipo reiškinius. Su eilutėmis yra apibrėžta viena operacija ir keletas funkcijų. Panagrinėsime jas.

e+ee  Operacijos rezultatas – eilutė, gauta sujungus jos operandus – eilutes e ir ee į vieną eilutę, pavyzdžiui,

'PROGRAMA' + 'AVIMAS'  => 'PROGRAMAVIMAS'

copy(e, i, n)   Funkcijos rezultatas – n simbolių ilgio eilutė – eilutės e dalis, kurios pradžia yra i-asis jos simbolis, pavyzdžiui,

copy('informacija', 3, 5) => 'forma'

length(e)    Funkcijos rezultatas – eilutės e ilgis, pavyzdžiui, 
length('Jonas ir Ona') => 12

pos(e, ee)   Funkcijos rezultatas – simbolio eilės numeris (pozicija) eilutėje ee, nuo kurio prasideda eilutė e, pavyzdžiui,

pos('ir', 'Jonas ir Ona') => 7

Jei eilutės e nėra eilutėje ee, tai pos(e, ee) = 0.

Darbą su eilutėmis pailiustruosime pavyzdžiais.

1 pavyzdys. Mažosios raidės keitimas didžiąja.

function didr (s: char): char;
   const dr = 'AĄBCČDEĘĖFGHIYĮJKLMNOPQRSŠTUŲŪWVXZŽ';
            mr = 'aąbcčdeęėfghiyįjklmnopqrsštuųūwvxxž';
   var nr: integer;                                             { raidės numeris }
         e: string;
begin
  
nr := pos(s, mr);
   if nr = 0 then e := s
               else e := copy(dr, nr, 1);
   didr := e[1]
end;

2 pavyzdys. Pranešimo šifravimas Cezario šifru. Šifruojama šitaip: n-toji abėcėlės raidė keičiama n+2-ąja, priešpaskutinė – pirmąja, o paskutinė – antrąja. Kiti simboliai nešifruojami.

Parašysime vienos raidės šifravimo funkciją.

function Cezaris (s: char): char;
   const dr = 'AĄBCČDEĘĖFGHIYĮJKLMNOPQRSŠTUŲŪWVXZŽ';
            mr = 'aąbcčdeęėfghiyįjklmnopqrsštuųūwvxzž';
   var nr: integer;                                  { raidės numeris }
         ss: string;                                  { užšifruota raidė }
begin
  
ss := s;
   nr := pos(s, dr);
   if nr <> 0                                          { šifruojama didžioji raidė }
      then
         begin
            if
nr = length(dr)
               then ss := copy(dr, 2, 1)        { paskutinė }
               else if nr = length(dr)-1
                    then r := copy(dr, 1, 1)      { priešpaskutinė }
                    else r := copy(dr, nr+2, 1) { n+2 }
         end;
  
nr := pos(s, mr);
   if nr <> 0                                           { šifruojama mažoji raidė }
      then
         begin
            if
nr = length(mr)
               then ss := copy(mr, 2, 1)       { paskutinė }
               else if nr = length(mr)-1
                   then ss := copy(mr, 1, 1)    { priešpaskutinė }
                   else ss := copy(mr, nr+2, 1) { n+2 }
         end;
  
Cezaris := ss[1]
end;

Šioje funkcijoje naudojome atskirus didžiųjų ir mažųjų raidžių sąrašus (konstantas dr ir mr). Dėl to atskirai teko šifruoti didžiąsias ir mažąsias raides, ir funkcijos algoritme gavome dvi labai panašias dalis. Jas galima būtų aprašyti funkcija. Kitas programos patobulinimo kelias – vartoti bendrą didžiųjų ir mažųjų raidžių sąrašą

'AaĄąBb...ZzŽž'

Pastaruoju atveju raidę n reikėtų keisti ne n+2-ąja, o n+4-ąja raide ir atskirai rašyti paskutinių keturių raidžių keitimą pirmosiomis keturiomis.

Uždaviniai

9.2.1. Parašykite funkciją mažr, kuri didžiąją raidę pakeistų mažąja, t.y. atvirkščią 
         1 pavyzdžio funkcijai didr.

9.2.2. Ar galima tvirtinti, kad

a) didr(mažr(c)) = c;
b) mažr(didr(c)) = c

čia didr – 1 pavyzdžio funkcija,
mažr – 1 uždavinio funkcija.

Praktikos darbas

9.2.1. Pranešimų šifravimas. Parašykite dvi programas teksto byloms šifruoti: vieną užšifruojančią atvirą tekstą Cezario kodu, kitą – iššifruojančią. Vienos raidės šifravimui panaudokite 2 pavyzdžio funkciją.

Programas išbandykite su bet kokiomis jūsų kompiuteryje esančiomis tekstų bylomis. Byla, gauta ją užšifravus ir vėl iššifravus, turi sutapti su pradine.

9.3. Žodžių rikiavimas

Žodžiai rikiuojami pagal abėcėlę. Skirtingų kalbų abėcėlės turi skirtingus raidžių rinkinius. Skiriasi ir aidžių išdėstymas. Pavyzdžiui, lietuviškoje abėcėlėje raidė y yra greta raidės i, o angliškoje abėcėlėje raidė y yra priešpaskutinė, prieš z. Paskalio kalboje pagrindinis dėmesys skiriamas skaičiavimams, o ne tekstų tvarkymui. Kalbos standarte nėra apibrėžtas simbolių išdėstymas. Tuo pačiu neapibrėžti ir simbolių lyginimo operacijų rezultatai. Tas pats pasakytina ir apie daugumą Paskalio dialektų. Todėl parodysime, kaip galima pačiam programuotojui apibrėžti simbolių išdėstymo eilę ir pagal ją rikiuoti simbolius bei žodžius.

Simbolių išdėstymą galima apibrėžti juos surašius abėcėlės tvarka į simbolių eilutę:

abc = 'aąbcčdeėęfghiįyjklmnoprsštuųūvzž'

Raidės eilės numerį abėcėlėje galima gauti taikant standartinę funkciją pos, o pagal gautą funkcijos rezultatą jau galima rikiuoti simbolius arba žodžius.

Pavyzdys. Procedūra žodžiams rikiuoti pagal abėcėlę.

const žsk = ...;                                 { žodžių skaičius }
type žodis = string;
        žodžiai = array [1..žsk] of žodis;
procedure rikiavimas (var žž: žodžiai);
   var ž: žodis;
         žž: žodžiai;
         j, k: 1..žsk; { žodžių masyvo indeksai }
   function daugiau (a, b: žodis): boolean;
      const abc = 'aąbcčdeęėfghiįyjklmnoprsštuųūvzž';
      var i: integer;
            lygu: boolean;
   begin
     
i := 1;
      lygu := true;
      while lygu and (i <= length(a)) and (i <= length(b)) do
          begin
             
lygu := copy(a, i, 1) = copy(b, i, 1);
              i := i+1
          end;
      if lygu
          then daugiau := length(a) > length(b)
          else daugiau :=
                   pos(copy(a, i, 1), abc) > pos(copy(a, i, 1), abc)
   end;
begin
   for
k := 1 to žsk-1 do
      for
j := 1 to žsk-k do
         if
daugiau(m[j], m[j+1]) then
            begin
{ du gretimi žodžiai keičiami vietomis }
                ž := žž[j+1];
                žž[j+1] := žž[j];
                žž[j] := ž
            end
end
;

Šioje procedūroje vartojamos tik mažosios raidės.

Praktikos darbas

9.3.1. Žodynas. Žodynuose įprasta žodžius rikiuoti taip, kad šios raidžių grupės būtų laikomos lygiavertėmis:

a, ą;
e, ę, ė
i, į, y;
u, ų, ū

Parašykite žodžių su lygiavertėmis raidėmis rikiavimo procedūrą.

9.4. Teksto redagavimas

Knygų, straipsnių ir kitokių tekstų rašymas yra kūrybinis darbas ir jį žmogus atlieka geriau už kompiuterį. Tačiau yra daugybė tekstų analizės ir tvarkymo darbų, kuriuos galima pavesti kompiuteriui.

Tekstai redaguojami literatūriškai ir techniškai. Literatūrinis redagavimas – tai geresnių išraiškos priemonių, geresnių terminų parinkimas, įvairūs stilistiniai taisymai, kurių tikslas – padaryti tekstą taisyklingesnį, logiškesnį ir aiškesnį nekeičiant jo esmės bei juo perteikiamos informacijos. Techninis redagavimas – tai teksto suskirstymas į puslapius ir jo išdėstymas puslapiuose, tarpų tarp žodžių sureguliavimas.

Redagavimui, ypač techniniam naudojami kompiuteriai. Tam yra parašytos specialios programos, vadinamos tekstų dorokliais arba redaktoriais, kurios padeda rinkti ir taisyti tekstus. Čia pateiksime porą nedidelių programų, kurios padės susidaryti vaizdą apie tekstų doroklių atliekamus veiksmus.

1 pavyzdys. Pradiniai duomenys – tekstas, sudarytas iš žodžių. Žodžiai skiriami tarpais. Laikoma, kad žodžiui priklauso ir greta jo parašyti, bet neatskirti tarpais skyrybos ženklai. Tarp gretimų žodžių gali būti vienas ir daugiau tarpų. Pateikiame programą, kuri tekstą pertvarko taip, kad tarp gretimų žodžių būtų tik po vieną tarpą, t.y., panaikina nebūtinus tarpus.

program red;
   var prad,                                      { padinių duomenų byla }
         rez: text;                                { rezultatų byla }
         s,                                          { tik ką perskaitytas simbolis }
         sa: char;                                { anksčiau perskaitytas simbolis }
begin
  
assign(prad, 'PRADDUOM.TEK'); reset(prad);
   assign(rez, 'REZULT.TEK'); rewrite(rez);
   sa := ' ';
   while not eof(prad) do
       begin
         
read(prad, s);
          if (s = ' ') and (s = ' ')
             then writeln(rez, ' ')               { rašomas tik vienas (pirmas) tarpas }
             else if s <> ' '
                  then write(rez, s)
          sa := s;                     { dabar perskaitytas simbolis tampa ankstesniu }
          if eoln(prad)
              then begin
                         
writeln(rez);
                          read(prad);
                          sa := s
                      end
       end;
  
close(rez)
end;

Pradinių duomenų pavyzdys:

Kalnai   kelmuoti,     pakalnės nuplikę!
    Kas jūsų grožei    senobinei    tiki?
  Kur toj puikybė jūsų      pasidėjo?
Kur   ramus   jūsų   ūžimas   nuo   vėjo,
Kai          balto miško  lapeliai šlamėjo
     Ir senos    pušys    siūravo,   braškėjo?

Rezultatų pavyzdys:

Kalnai kelmuoti, pakalnės nuplikę!
Kas jūsų grožei senobinei tiki?
Kur toj puikybė jūsų pasidėjo?
Kur ramus jūsų ūžimas nuo vėjo,
Kai balto miško lapeliai šlamėjo
Ir senos pušys siūravo, braškėjo?

2 pavyzdys. Parašysime programą, kuri ne tik pašalina nereikalingus tarpus tarp žodžių, bet ir suskirsto tekstą į vienodo ilgio eilutes. Paskutinis žodis eilutėje gali netilpti. Tada jis (visas) keliamas į naują eilutę.

Programa turėtų būti panaši į 1 pavyzdžio programą. Tačiau joje negalima iš karto rašyti tik ką surinktą žodžio simbolį į rezultatų bylą, o pirmiau reikia įsiminti visą žodį, nes kol žodis neperskaitytas iki galo, tol neaišku, ar jis tilps toje eilutėje, ar reikės jį kelti į naują.

program taisymai;
   const eil = 60;                       { teksto (puslapio eilutės ilgis }
   var prad,                               { padinių duomenų byla }
         rez: text;                         { rezultatų byla }
         s: char;                           { tik ką perskaitytas simbolis }
žodis: string; { perskaitytų simbolių seka be tarpų }
poz: integer; { pirmoji laisva pozicija teksto (puslapio) eilutėje }
k: 1..eil;
begin
assign(prad, 'PRADDUOM.TEK'); reset(prad);
assign(rez, 'REZULT.TEK'); rewrite(rez);
žodis := '';
poz := 1;
while not eof(prad) do
begin
if
eoln(prad)
then begin
readln(prad);
s := ' '
end
else
read(prad, s);
if s <> ' ' then žodis := žodis+s;
if (length(žodis) = eil) or
eof(prad) or
(length(žodis) > 0) and (s = ' ')
then begin { write }
if (poz+length(žodis)-1 > eil) and (poz > 1)
then begin { pereinama į naują eilutę }
writeln(rez);
poz := 1
end;
if poz > 1 { eilutė jau pradėta }
then begin { rašomas tarpas tarp gretimų žodžių }
write(rez, ' ');
poz := poz + 1
end;
write(rez, žodis); { rašomas žodis }
poz := poz + length(žodis);
žodis := ''
end
end
;
writeln(rez); close(rez)
end.

Čia pateikėme teksto tvarkymo programas naudodami simbolių eilutes. Paskalio standartas ir kai kurie jo dialektai neturi simbolių eilučių tipo ir kintamųjų. Be jų taip pat galima programuoti tokius uždavinius, tik vietoj simbolių eilučių reikia naudoti simbolių masyvus. Masyvai neturi eilutėms būdingų operacijų (operacijos +, funkcijos lenght), todėl tokiais atvejais jų veiksmus reikėtų programuoti – išreikšti esamomis operacijomis ir funkcijomis.

Praktikos darbas

9.4.1. Skyrybos ženklų tvarkymo programa. Rašybos taisyklės nustato, tarp kurių skyrybos ženklų ir žodžių turi būti paliktas tarpas (arba daugiau tarpų) arba tarpo neturi būti. Taisyklės yra tokios:

1. Po taško (sakinio pabaigoje), dvitaškio, kabliataškio ir kablelio reikia palikti tarpą, o prieš šiuos ženklus tarpo nereikia.
2. Skliaustų arba kabučių išorėje reikia palikti tarpą, o jų viduje tarpo nereikia.
3. Abipus brūkšnio paliekami tarpai.
4. Abipus brūkšnelio tarpų nereikia.

Parašykite programą šiam uždaviniui spręsti.

E Ankstesnis puslapis

3 Turinys

Kitas puslapis F

tus0.gif (69 bytes)