В) Введите программу решения директорской задачи (см. предыдущую страницу), а затем запустите её в пошаговом режиме (клавишей F7). Перед запуском вставьте все переменные в окно обзора переменных «Watch» и проследите за их изменением. Напомню, что о средствах отладки рассказано в главе 21.
Глава 37
Ввод и вывод множеств
Мы узнали о множествах и приспособили их к директорской задаче. Чтобы покончить с нею доделаем ещё пару пустяков: организуем ввод и вывод множеств. Для ввода-вывода строк и простых типов данных годятся процедуры Read[ln] и Write[ln]. Но сейчас все не так просто, – эти процедуры не способны работать, ни с множествами, ни с другими сложными типами данных. Однако ж «нормальные герои всегда идут в обход», – пойдем так и на этот раз.
Начнем с вывода числового множества на экран (или в файл, – что одно и то же). Так мы получим средство для последующей проверки вводимых множеств.
Раз уж процедура Writeln не печатает множество одним махом, выведем каждый его элемент по отдельности – ведь это обычные числа или символы. Проверяя все возможные элементы множества, будем печатать лишь те, что входят в него – в этом основная идея. Напомню, что для такой проверки подходит операция IN. Дополнив её циклом со счетчиком, соорудим несложную процедуру распечатки числового множества. Вот она вместе с программой для её проверки.
{ P_37_1 – вывод множества в файл }
type TSet = set of 1..255; { объявление типа «множество» }
{----- Процедура вывода множества в файл -----}
procedure WriteSet(var aFile: text; const aSet : TSet);
var k : integer;
begin
for k:=1 to 255 do { цикл по всем элементам множества}
if k in aSet { если K входит в множество }
then Write(aFile, k:4); { печатаем в строке }
Writeln(aFile); { по окончании – переход на следующую строку }
end;
{----- Программа для проверки процедуры WriteSet -----}
var S1 : TSet; F: text;
begin
S1:= [3, 10, 25]; { значение множества }
WriteSet(F, S1); { печатаем }
Readln;
Close(F);
end.
В первой строке объявлен тип данных TSet, он может содержать целые числа от 1 до 255. Процедура распечатки WriteSet принимает по ссылке два параметра: файловую переменную и множество, которое надо распечатать. Внутри процедуры работает цикл FOR, перебирающий все возможные элементы множества. Те из них, что содержатся в нём, печатаются в текущей строке. По завершении цикла оператор Writeln переводит позицию записи на следующую строку файла.
Обратите внимание: множество передано в процедуру по ссылке CONST. Передача в процедуры множеств, строк и других сложных типов данных по ссылкам CONST и VAR — это обычная практика. Так повышается скорость работы программ и уменьшается объём памяти, занимаемый параметрами.
Теперь взгляните на оператор Assign(F,''), который назначает файловой переменной пустое имя файла. Так файловая переменная связывается с экраном дисплея (при выводе данных), либо с клавиатурой (при вводе). А когда вам потребуется вывести результаты в дисковый файл, достаточно будет задать нужное имя файла, не меняя процедуры WriteSet (этот прием – подстановка пустого имени – не работает в Pascal ABCNet).
for k in aSet do Write(aFile, k:4);
Разобравшись с распечаткой множества, перейдем к вводу его из файла. Есть соображения на этот счет? Здесь пригодится опыт чтения чисел из строки текстового файла, – вспомните обработку классного журнала. Добавить число к множеству мы тоже умеем: для этого надо объединить его с множеством, состоящим из добавляемого числа. На этих идеях построена процедура ввода, показанная ниже вместе с тестирующей её программой.
{ P_37_2 – ввод и вывод числового множества }
type TSet = set of 1..255; { объявление типа «множество» }
{----- Процедура чтения множества из файла -----}