Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лаб_раб_8С++.doc
Скачиваний:
32
Добавлен:
18.03.2015
Размер:
156 Кб
Скачать
☆

2 Задание

2.1 Организация массива структур

Составить программу, в которой будут вводиться 7 - 10 строк таблицы, образец которой приведен в Вашем варианте индивидуального задания к лабораторной работе и выводится на экран таблица - сразу же после ввода и после сортировки ее по значениям в первом столбце.

Разберем решение данной задачи на следующем примере:

Имеется совокупность данных о буддийских монастырях Японии периода Нара. Требуется организовать ввод, сортировку и вывод данных.

Буддийские монастыри Японии периода Нара

Название

Школа

Количество монахов

Площадь земли (га)

Тодайдзи

Т

220

368.8

Якусидзи

С

50

54.7

Дайандзи

Д

10

12.2

Примечание: Т - Тэндай; С - Сингон; Д - Дзедзицу

Алгоритм решения, приведенный ниже на рисунке 1, является типовым алгоритмом обработки массива, элементами которого являются описания монастырей.

Алгоритм начинается с ввода значений элементов этого массива. Ввод происходит в цикле со счетчиком n, который изменяется от 0 до 9 (блок 2), но как мы увидим ниже, выход из цикла может происходить и до того, как счетчик достигнет последнего значения. В каждой итерации циклу выводится приглашение (блок 3) и вводятся значения составных частей описания монастыря (блоки 4, 6, 7, 8). Но сразу же после ввода первой составляющей - названия - проверяется ее значения (блок 5). Если введено название "***", то дальнейшего ввода не происходит, а сразу выполняется выход из цикла. В любом случае после выхода в переменной n остается количество введенных элементов. Таким образом, программа может обрабатывать массив из 10 или меньше элементов - сколько их было введено. Признаком конца ввода является название "***".

Далее печатаем заголовок таблицы (блок 9) и в цикле (блоки 10, 11) - строки таблицы с данными. Поскольку параметр этого цикла изменяется от 0 до n-1, будет напечатано n строк.

Следующий сложный цикл реализует сортировку таблицы по алгоритму простой обменной выборки. Сортировка выполняется с помощью вложенного цикла (блок 12). В первой итерации внешнего цикла выполняется поиск элемента массива с минимальным значением поля name. Для этого сначала минимальным элементом считается первый элемент (блок 13). Потом в цикле (блок 14) пересматриваются остальные элементы массива, и каждый сравнивается с минимальным (блок 15). Если поле name очередного элемента меньше, чем минимального, то теперь этот элемент считается минимальным (блок 16). Индекс минимального элемента записывается в переменную m. После выхода из внутреннего цикла, если найденный минимальный элемент не первый (блок 17), то он меняется местами с первым (блок 18). Таким образом, минимальный элемент массива становится на свое место. В следующей итерации внешнего цикла выполняется поиск минимума среди элементов массива, начиная со второго, в третьей - начиная с третьего и т.д. После выхода из внешнего цикла массив оказывается отсортированным.

Вывод отсортированного массива (блоки 19 - 21) происходит точно так же, как и вывод начального массива (блоки 9 - 11).

Рисунок 1. Алгоритм программы

Элементом массива является описание объекта. Поскольку описание состоит из нескольких составных частей разного типа, для него используем структуру языка C++. Описание этой структуры будет иметь вид:

struct mon {

char name[15]; /* название */

char sc; /* школа */

int cnt; /* количество монахов */

float sq; /* площадь */ };

Нам нужно будет иметь массив элементов указанного типа, следовательно, объявляем: struct mon mm[10];

Для выполнения перестановки элементов массива нужна будет еще рабочая область памяти того же типа, что и элементы массива, поэтому вводимо еще:

struct mon x;

Текст программы начинаем с включения файла stdio.h. Поскольку нам придется проводить сравнение (блок 15) поля name в элементах массива, а это поле - символьная строка, включаем также файл string.h, где описаны функции работы с символьными строками. В самом начале программы вводим также описание структуры mon и одновременно - объявление массива mm. Массив будет размещен в статической памяти.

Потом открывается главная функция программы, и в ней объявляются остальные переменные. Открывается простой цикл со счетчиком n, в каждой итерации цикла выводится приглашение и вводятся значения полей очередного элемента массива. Сравнение поля name с константой "***" - признаком конца ввода выполняется с помощью функции strcmp(). Если введен признак конца, происходит досрочный выход из цикла за оператором break.

Вывод массива состоит из вывода заголовка как нескольких строк-констант и вывода в цикле строк с фактическими данными.

Следующие операторы программы подробно реализуют блоки 12 - 17 схемы алгоритма (для сравнения символьных строк применяется функция strcmp()). Детального рассмотрения требует только реализация блока 18 - перестановка элементов. Во-первых, при перестановке используется рабочая структура x: сначала содержимое i-го элемента пересылается в x, потом содержимое m-го элемента пересылается в i-ый элемент, а потом содержимое x пересылается в m-ый элемент. Во-вторых, операция присваивания, которая обычно применяется для пересылки значений, не может применяться к структуре в целом, так что присваивания происходит для каждого поля отдельно. К тому же, поле name является символьной строкой, а строки тоже не могут присваиваться прямо, а только - через функцию strcpy().

Полный текст программы приведен ниже.

#include <iostream.h>

#include <conio.h>

#include <string.h>

#include <stdio.h>

/* Описание структуры, которая представляет монастырь */

struct mon {

char name[15]; /* название */

char sc; /* школа */

int cnt; /* количество монахов */

float sq; /* площадь */

} mm[10]; /* определение массива монастырей */

int main(void) {

struct mon x; /* рабочая переменная */

int n; /* количество элементов в массиве */

int i, j; /* текущие индексы в массиве */

int m; /* индекс минимального элемента */

for (n=0; n<10; n++) {

cout << "Vvedite: nazvanie, shkolu, kol-vo, ploshad monastiria " << n+1;

cin>>mm[n].name;

if (!strcmp(mm[n].name,"***")) break;

cin>> mm[n].sc;

cin>> mm[n].cnt;

cin>> mm[n].sq;

}

cout <<"------------------------------------------------------------\n";

cout <<"| monastiri |\n";

cout <<"|----------------------------------------------------------|\n";

cout <<"| nazvanie | shkola | Kolichestvo | Ploshad |\n";

cout <<"| | | monahov | zemel |\n";

cout <<"|---------------|----------|--------------|----------------|\n";

for (i=0; i<n; i++)

printf("| %9s | %c | %3d | %5.1f |\n", mm[i].name, mm[i].sc, mm[i].cnt, mm[i].sq);

cout<<"------------------------------------------------------------\n";

for (i=0; i<n-1; i++) {

m=i; /* минимальный элемент - первый */

for (j=i+1; j<n; j++)

/* если текущий элемент > минимального, он становится минимальным */

if (strcmp(mm[m].name, mm[j].name)>0) m=j;

if (m>i) {

/* перестановка первого и минимального элементов */

strcpy(x.name,mm[i].name);

x.sc=mm[i].sc;

x.cnt=mm[i].cnt;

x.sq=mm[i].sq;

strcpy(mm[i].name,mm[m].name);

mm[i].sc=mm[m].sc;

mm[i].cnt=mm[m].cnt;

mm[i].sq=mm[m].sq;

strcpy(mm[m].name,x.name);

mm[m].sc=x.sc;

mm[m].cnt=x.cnt;

mm[m].sq=x.sq;

}

}

cout <<"------------------------------------------------------------\n";

cout <<"| monastiri |\n";

cout <<"|----------------------------------------------------------|\n";

cout <<"| nazvanie | shkola | Kolichestvo | Ploshad |\n";

cout <<"| | | monahov | zemel |\n";

cout <<"|---------------|----------|--------------|----------------|\n";

for (i=0; i<n; i++)

printf("| %9s | %c | %3d | %5.1f |\n", mm[i].name, mm[i].sc, mm[i].cnt, mm[i].sq);

cout<<"------------------------------------------------------------\n";

getch() ;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]