Для упорядочивания результатов во втором задании вместо сортировки массива a по убыванию используется другой алгоритм, связанный с последовательным нахождением максимального элемента, выводом этого элемента и его порчей" (заменой его значения на 0). Обычная сортировка массива в данном случае не позволит получить требуемый набор данных, так как при перемене местами значений элементов в массиве a будет потеряна связь с номером школы (который определяется по индексу элемента). Заметим, что возможен и вариант получения упорядоченного набора данных с помощью сортировки, однако для этого надо использовать массив записей, полями которых являются максимальный год и номер школы.
Во втором задании результаты должны упорядочиваться по набору ключей: первый (главный) ключ -- максимальный год (сортируется по убыванию), второй (подчиненный) ключ -- номер школы (сортируется по возрастанию). Использованный нами способ упорядочивания обеспечивает автоматическую сортировку по подчиненному ключу, так как при поиске очередного максимума массив a перебирается по возрастанию индексов, и поэтому в результате находится номер первого максимального элемента.
Прочие фрагменты процедуры Exam2 дополнительных комментариев не требуют.
Вызов процедуры Exam2 надо добавить в конец оператора case процедуры InitTask, связав его с номерами 17 и 18:
procedure InitTask(num: integer);
begin
case num of
1..2: UseTask('ExamBegin', 70 + num);
3..4: Exam1(num - 2);
5..16: UseTask('ExamTaskC', 20 + num);
17..18: Exam2(num - 16);
end;
end;
Кроме того, необходимо опять откорректировать параметр процедуры CreateGroup, определяющий количество заданий, положив его равным 18.
При нажатии клавиши [F9] на экране появится окно задачника с последним заданием данной группы (на рисунке приведен вид окна после прокрутки раздела с формулировкой задания):
Если теперь опять заменить символ ?" на символ "# " в параметре процедуры Task тестирующей программы, то при нажатии [F9] мы увидим html-страницу с описанием группы, которое теперь содержит не только импортированные, но и реализованные нами задания:
Поскольку при создании новых заданий мы указали в качестве параметра процедур CreateTask названия подгрупп (и разместили новые задания после заданий из данных подгрупп), новые задания отображаются в составе этих подгрупп: ExamDemo3 и ExamDemo4 -- в подгруппе "Преобразование массивов", а ExamDemo17 и ExamDemo18 -- в подгруппе "Обработка сложных наборов данных".
Уроки PascalABC .NET
ABCObjects: быстрое введение
Основными типами графических объектов, определенными в модуле ABCObjects, являются RectangleABC, SquareABC, EllipseABC, CircleABC, TextABC, RegularPolygonABC, StarABC, PictureABC, MultiPictureABC, BoardABC и ContainerABC.
Типы графических объектов представляют собой классы, состоящие из методов и свойств, а также нуждающиеся в конструировании перед первым использованием. Изменение свойств влияет на внешний вид и поведение графических объектов. Например, при изменении свойств Width и Height меняются размеры графического объекта, при изменении свойства Color - цвет графического объекта и т.д. Вызов методов графического объекта возвращает или меняет его характеристики. Например, при вызове метода ToFront графический объект перемещается на передний план, а вызов метода Intersect(g) возвращает, пересекается ли текущий объект с объектом g.
Все графические объекты являются разновидностями класса ObjectABC, который содержит общие для всех свойства и методы.
Создадим два перекрывающихся графических объекта:
uses ABCObjects,GraphABC;
var
r: RectangleABC;
c: CircleABC;
begin
r := new RectangleABC(70,50,200,100,clMoneyGreen);
c := new CircleABC(120,80,110,clBlue);
end.
После запуска программы увидим на экране следующее:
Поменяем некоторые свойства графических объектов и вызовем метод MoveOn для окружности, дописав в конец программы следующие строки:
r.Width := 150;
c.Color := clRed;
c.MoveOn(30,30);
После запуска программы:
Добавим в конец программы следующие строки:
c.Number := 8;
r.Text := 'Hello';
r.ToFront;
После запуска программы:
ABCObjects: контейнеры графических объектов
Класс ContainerABC представляет собой контейнер графических объектов. Он также является потомком ObjectABC, но при создании не содержит ни одного объекта. Он добавляет следующий интерфейс:
procedure Add(g: ObjectABC);
property Count: integer; // количество объектов
property Objects[i: integer]: ObjectABC; // i-тый объект
При масштабировании ContainerABC производится масштабирование всех входящих в него объектов. При добавлении объекта в ContainerABC его свойство Owner становится равным этому ContainerABC. При присваивании свойству Owner объекта его владелец меняется, при этом объект перерисовывается как принадлежащий новому владельцу. При присваивании свойству Owner объекта значения nil он перестает иметь владельца и отображается непосредственно в графическом окне.
Рассмотрим следующую программу:
uses ABCObjects,GraphABC;
var
c1,c2: ContainerABC;
r: CircleABC;
begin
SetWindowSize(300,300);
c1 := new ContainerABC(50,30);
c1.Add(new RectangleABC(0,0,200,100,clGreen));
r := new CircleABC(15,15,70,clYellow);
end.
После ее запуска графический экран имеет вид:
Контейнер c1 содержит зеленый прямоугольник, а объект r не имеет владельца (r.Owner=nil). Нетрудно убедиться, что ObjectsCount=2 (контейнер и круг), а c1.Count=1.
Добавим круг в контейнер, дописав в конец программы строчку
c1.Add(r);
После запуска программы графический экран примет вид:
Круг r теперь принадлежит контейнеру (r.Owner=с2), ObjectsCount=1 (только контейнер), а c1.Count=2. Кроме этого, координаты круга пересчитываются относительно координат контейнера-владельца (они по-прежнему равны (15,15), но относительно левого верхнего угла контейнера c1).
Такой же эффект можно было получить от оператора
r.Owner := c1;
Создадим второй контейнер c2 и поменяем владельца у r на c2. Для этого допишем в конец строки:
c2 := new ContainerABC(50,160);
c2.Add(new RectangleABC(0,0,200,100,clMoneyGreen));
r.Owner := c2;
После запуска программы графический экран примет вид:
Как мы видим, круг r поменял владельца, и теперь имеет координаты (15,15), но относительно левого верхнего угла нового владельца c2.