Литмир - Электронная Библиотека

const Cx = 40; { количество столбцов (ширина) }

      Cy = 20; { количество строк (высота) }

type TDesk = array [1..Cy, 1..Cx] of boolean; { тип «рекламный щит» }

var Desk : TDesk; { переменная «рекламный щит» }

Здесь пределы для индексов указаны через константы Cx и Cy. Заполнить матрицу значением FALSE можно двумя вложенными циклами:

      for y:=1 to Cy do

      for x:=1 to Cx do Desk[y, x]:= False;

То же самое делается быстрее и короче известной вам процедурой заполнения FillChar:

      FillChar(Desk, SizeOf(Desk), false);

Здесь значение SizeOf(Desk) составит 800 – это количество элементов матрицы.

Можно обрабатывать и отдельные строки, и отдельные столбцы матрицы. Например, заполнить значением TRUE 5-й столбец:

      for y:=1 to Cy do Desk[y, 5] := True;

А для заполнения 3-й строки организовать такой цикл:

      for x:=1 to Cx do Desk[3, x] := True;

Если вам понятна техника работы с матрицами, перейдем к программе «P_49_2».

Начнем с процедуры ReadDesk, что вводит матрицу из файла. Условимся считать, что крестикам в матрице Desk соответствует TRUE, а ноликам – FALSE. Входной файл обрабатываем построчно: сначала очередную строку читаем во вспомогательную строковую переменную S, а затем символы этой строки преобразуем в булевы значения оператором сравнения (вы помните, что оператор сравнения дает булев результат?).

      Desk[y,x]:= S[x]='+'; { TRUE, если S[x] содержит крестик }

Следовательно, для ввода матрицы нужны два вложенных цикла: внешний – по строкам и внутренний – по столбцам.

Схоже работает и процедура WriteDesk, выводящая матрицу на экран. Здесь внутренний цикл формирует строку из 40 символов, каждый из которых может быть либо крестиком либо ноликом. Выбор пары символов – дело вкуса, в нашем случае пара определяется строковой константой CSymbols.

const CSymbols : string = '0+';

Нужный символ из этой строки выбирается по индексу.

      S:= S + CSymbols[1+ Ord(Desk[y, x])];

Так, для значений Desk[y,x], равных FALSE, будет выбран первый символ строки ('0'), а для TRUE – второй ('+'), что равнозначно следующему громоздкому оператору.

      if Desk[y, x]

      then S:= S + CSymbols[2]

      else S:= S + CSymbols[1]

Далее следуют две простые процедуры зеркального отражения матрицы относительно горизонтальной и вертикальной осей, – они всего лишь переставляют симметрично расположенные элементы.

Процедура инверсии рекламного щита ещё проще, – она меняет значения элементов матрицы на противоположные. Наконец, в главной программе после чтения из файла исходного изображения организован цикл ввода и обработки команд пользователя. Вводя одну из трёх команд (1, 2 или 3), пользователь крутит изображение туда-сюда, а также инвертирует его. Вот полный текст этой программы.

{ P_49_2 – Рекламная панель "крестики-нолики" }

const Cx = 40; { количество столбцов (ширина) }

      Cy = 20; { количество строк (высота) }

type TDesk = array [1..Cy, 1..Cx] of boolean;

var Desk : TDesk;

      { Чтение исходного состояния панели из текстового файла }

procedure ReadDesk(var F: Text);

var x, y: integer; { x – индекс столбца, y – индекс строки }

      S: string;

begin

FillChar(Desk, SizeOf(Desk), false);

y:=1;

while not Eof(F) and (y<=Cy) do begin

      Readln(F, S);

      x:=1;

      while (x<=Length(S)) and (x<=Cx) do begin

      Desk[y,x]:= S[x]='+';

      Inc(x); { x:= x+1 }

      end;

      Inc(y);       { y:= y+1 }

end

end;

      { Вывод текущего состояния панели в текстовый файл }

procedure WriteDesk(var F: Text);

const CSymbols : string = '0+';

var x, y: integer; S: string;

begin

for y:=1 to Cy do begin

      S:='';

      for x:=1 to Cx do S:= S + CSymbols[1+ Ord(Desk[y, x])];

      Writeln(F, S);

end;

end;

      { Вспомогательная процедура обмена местами булевых переменных }

procedure Swap (var a, b : boolean);

var t : boolean;

begin

t:=a; a:=b; b:=t;

end;

      { Отражение относительно вертикальной оси }

procedure Vert;

var x, y: integer;

begin

for y:=1 to Cy do

for x:=1 to Cx div 2 do Swap(Desk[y, x], Desk[y, Cx-x+1])

end;

      { Отражение относительно горизонтальной оси }

procedure Horisont;

var x, y: integer;

begin

for y:=1 to Cy div 2 do

      for x:=1 to Cx do Swap(Desk[y, x], Desk[Cy-y+1, x])

end;

      { Инверсия рекламной панели }

procedure Invers;

var x, y: integer;

begin

for y:=1 to Cy do

      for x:=1 to Cx do Desk[y, x]:= not Desk[y, x]

end;

var FileIn : Text;

      cmd : integer;

begin       {=== Главная программа ===}

Assign(FileIn, 'P_46_2.in'); Reset(FileIn);

ReadDesk(FileIn);

Close(FileIn);

repeat

      WriteDesk(Output);       { вывод «щита» на экран }

      Writeln;

      Write('1- Вертикальная; 2- Горизонтальная; 3- Инверсия, 0- Выход : ');

      Readln(cmd);       { Ввод команды }

      case cmd of

      1: Vert;       { отражение относительно вертикальной оси }

      2: Horisont; { отражение относительно горизонтальной оси }

      3: Invers;       { инверсия }

      else Break;       { выход из цикла и завершение программы }

      end;

until cmd=0;

end.

Добавлю ещё два слова о константе CSymbols.

const CSymbols : string = '0+';

Напомню, что такие константы, сопровождаемые описанием типа, называют типизированными и применяют для размещения данных в памяти.

Теперь, говоря по школьному, мы прошли тему массивов и двинемся дальше. Но с массивами впредь не расстанемся, поскольку, ни одна мало-мальски сложная задача без них не решается. Все только начинается!

Итоги

• Элементами массивов могут быть как простые, так и сложные типы данных, например, другие массивы или множества.

• Массив массивов называют двумерным массивом или матрицей.

• Для доступа к элементам матрицы необходимы два индекса: один – для столбца, другой – для строки.

А слабо?

А) По ходу строительства империи её бывшие границы – каналы – оказываются внутри новой страны и мешают перемещению граждан, – их лучше сровнять. Дополните программу «P_49_1» с тем, чтобы она печатала эти бывшие границы. Или слабо?

Б) Измените внутреннее представление рекламного щита так, чтобы вместо булевых элементов использовать символы. Внесите необходимые изменения в программу и проверьте её.

В) В 38-й главе для нахождения простых чисел мы воспользовались множеством. К сожалению, мощность множеств в Паскале невелика (256), поэтому находить большие простые числа мы не могли. Но выход есть – это массив булевых переменных. По сути, это множество, судите сами. Объявим массив из 1000 элементов.

87
{"b":"596178","o":1}