Cyklus v jazyku Pascal (tretia časť)

prvá časť -- druhá časť -- tretia časť

Pozrime si niekoľko príkladov, kde sa používa vnorený cyklus, čiže jeden cyklus v druhom. Načo je to dobré? Predstavme si napríklad, že máme pole čísel, a chceme zistiť, či sa tam vyskytujú dve rovnaké čísla. Jedna možnosť je porovnať každé s každým, a keď nájdeme zhodu, oznámiť výsledok. "Každé s každým" je vlastne dvojitý cyklus: ktoré porovnávame, a s ktorým porovnávame. Tu je jednoduchý príklad:

var
  pocet : Integer;
  cisla : Array[1..100] of Integer;
  nasli : Boolean;
  i, j : Integer;

begin
  Write('Pocet cisel: ');
  ReadLn(pocet);
  for i := 1 to pocet do begin
    Write('Zadajte cislo: ');
    ReadLn(cisla[i])
  end;
  nasli := false;
  for i := 1 to pocet do begin
    for j := 1 to pocet do begin
      if i <> j then begin
        if cisla[i] = cisla[j] then begin
          WriteLn('Na pozicii ', i, ' a ', j, ' je ', cisla[i]);
          nasli := true
        end
      end
    end
  end;
  if not nasli then begin
    WriteLn('Nenasla sa ziadna zhoda')
  end
end

Test "if i <> j" je v programe preto, aby nehlásil zhodu každého čísla so sebou samým. Čísla na pozíciách "i" a "j" porovnávame iba keď sú "i" a "j" rôzne.

Jednou z chýb uvedeného príkladu je, že každú zhodnú dvojicu vypíše dvakrát. Ak sú napríklad na pozíciách 2 a 4 rovnaké čísla, program najprv vypíše zhodu na pozíciách 2 a 4, a potom zhodu na pozíciách 4 a 2. Ako tomu zabrániť? Potrebujeme jednu z možných dvojíc "i" a "j" vylúčiť, a druhú ponechať. Môžeme napríklad dať podmienku, že "j" musí byť to väčšie číslo. Jedna z možností je zmeniť uvedený test "if i <> j" na "if i < j".

Druhá možnosť je nebrať za "j" všetky hodnoty od 1 po maximum, ale iba hodnoty väčšie od "i", inými slovami začínajúce od "i + 1". Vnútorný cyklus bude teda "for j := i + 1 to pocet". Nasledujúcu podmienku môžeme vyhodiť, lebo pri takomto postupe bude "j" vždy väčšie ako "i". Napríklad ak máme päť čísel, tak keď "i" bude mať najprv hodnotu 1, "j" vystrieda hodnoty od 2 po 5. V ďalšom kroku bude "i" rovné 2, a "j" vystrieda hodnoty od 3 po 5. Atď. Keď bude "i" rovné 4, "j" nadobudne iba hodnotu 5. A keď na záver bude "i" rovné 5, príkaz na opakovanie "j" bude žiadať opakovať od 6 do 5, čo znamená, že sa cyklus nevykoná ani raz.

var
  dlzka : Integer;
  x : Integer;

begin
  Write('Zadaj dlzku: ');
  ReadLn(dlzka);
  for x := 1 to dlzka do begin
    Write('*');
  end;
  WriteLn
end

Graficky názornejším príkladom dvojitých cyklov je vykresľovanie jednoduchých geometrických tvarov. V tomto príklade budeme skladať útvary z hviezdičiek. Ak chceme vypísať hviezdičky do riadku, vypýtame si dĺžku riadku, a pomocou príkazu "Write" vypíšeme príslušný počet hviezdičiek. Nakoniec riadok ukončíme príkazom "WriteLn".

var
  sirka : Integer;
  vyska : Integer;
  x, y : Integer;

begin
  Write('Zadaj sirku: ');
  ReadLn(sirka);
  Write('Zadaj vysku: ');
  ReadLn(vyska);
  for y := 1 to vyska do begin
    for x := 1 to sirka do begin
      Write('*');
    end;
    WriteLn
  end
end

V tomto príklade vnútorný cyklus vypíše hviezdičky v rámci riadku, a vonkajší cyklus vypíše príslušný počet riadkov. Keďže výstup na obrazovku funguje tak, že sa najprv musí vypísať celý riadok, a až potom začne nasledujúci, predstavuje vnútorný cyklus súradnicu "x" a vonkajší súradnicu "y".

var
  velkost : Integer;
  x, y : Integer;

begin
  Write('Zadaj velkost: ');
  ReadLn(velkost);
  for y := 1 to velkost do begin
    for x := 1 to velkost do begin
      Write('*');
    end;
    WriteLn;
  end
end

V prípade, že sa oba rozmery rovnajú, dostávame štvorec.

var
  velkost : Integer;
  x, y : Integer;

begin
  Write('Zadaj velkost: ');
  ReadLn(velkost);
  for y := 1 to velkost do begin
    for x := 1 to y do begin
      Write('*');
    end;
    WriteLn;
  end
end

Pomerne malou úpravou dostaneme trojuholník. Príkaz "for x := 1 to y" znamená, že v každom riadku sa vypíše toľko hviezdičiek, aké je poradové číslo toho riadku.

var
  velkost : Integer;
  x, y : Integer;

begin
  Write('Zadaj velkost: ');
  ReadLn(velkost);
  for y := 1 to velkost do begin
    for x := y to velkost do begin
      Write('*');
    end;
    WriteLn
  end
end

Iná úprava otočí trojuholník naopak. Príkaz "for x := y to velkost" vykreslí v každom riadku toľko hviezdičiek, koľko mu chýba do konca; čiže v poslednom 1 hviezdičku, v predposlednom 2, atď.

var
  velkost : Integer;
  x, y : Integer;

begin
  Write('Zadaj velkost: ');
  ReadLn(velkost);
  for y := 1 to velkost do begin
    for x := 1 to y - 1 do begin
      Write(' ');
    end;
    for x := y to velkost do begin
      Write('*');
    end;
    WriteLn
  end
end

Ak chceme dostať zvyšné polohy trojuholníka, treba pred hviezdičky vypísať niekoľko medzier. Môžeme to urobiť napríklad tak, že do vonkajšieho cyklu vložíme dva vnútorné.

var
  velkost : Integer;
  x, y : Integer;

begin
  Write('Zadaj velkost: ');
  ReadLn(velkost);
  for y := 1 to velkost do begin
    for x := 1 to velkost do begin
      if x < y then begin
        Write(' ')
      end else begin
        Write('*');
      end
    end;
    WriteLn
  end
end

Druhá možnosť je urobiť rovnaký cyklus ako keď vykresľujeme štvorec, ale vo vnútri si stanoviť podmienku, kedy sa vykreslí medzera a kedy hviezdička. Táto druhá možnosť je pružnejšia, pretože umožňuje zadať aj zložitejšie vzorce.

var
  velkost : Integer;
  x, y : Integer;

begin
  Write('Zadaj velkost: ');
  ReadLn(velkost);
  for y := 1 to velkost do begin
    for x := 1 to velkost do begin
      if x > 2*y then begin
        Write(' ')
      end else if y > 2*x then begin
        Write('.')
      end else begin
        Write('*');
      end
    end;
    WriteLn
  end
end

Komentáre: 0


Google