
Таблицы с прямым доступом
Внутренние таблицы с прямым доступом хранятся в виде вектора, причем индекс элемента таблицы определяется его ключом: i = f (ключ). Поэтому ключ в таблице хранить не нужно. В таблицах с прямым доступом поиск элементов происходит наиболее быстро.
Пример 17.2
Задача. Дан файл “patient.txt”, содержащий сведения о пациентах клиники. Каждая строка файла содержит запись об одном пациенте. Структура записи:
- фамилия и инициалы пациента (25 символов),
- дата поступления в виде: дд.мм.гг , например, 12.04.05 (9 символов с учетом пробела в конце),
- диагноз (не более 40 символов).
Вывести информацию о количестве пациентов, поступивших в заданном месяце (отдельно по дням месяца).
Пример строки файла:
Анисимов В.П. 20.03.05 инфаркт миокарда
Пример результата:
Введите номер месяца: 3
День Число пациентов
-------------------------------
12
10
25
9
. .
. .
. .
Метод решения задачи.
Программа будет работать с двумя таблицами: с внешней последовательной несортированной таблицей (хранящейся в файле) и внутренней таблицей с прямым доступом. Ключом при поиске элементов во внешней таблице будет номер месяца, а во внутренней – день месяца. Таблица с прямым доступом будет состоять из 31 элемента (по числу дней в месяце) и содержать число пациентов, поступивших в клинику в каждый день заданного месяца.
Вначале все элементы таблицы с прямым доступом обнуляются. После чтения очередной записи файла, если номер месяца совпадает с заданным, соответствующий элемент таблицы увеличивается на 1. Индекс элемента таблицы i = день месяца - 1.
Пример заполнения таблицы.
Файл: Таблица:
0 + 1 + 1 |
0 + 1 |
0 |
0 + 1 |
0 |
. . . |
0 |
Иванов С.И. 01.03.05 пневмония 0
Ганеев Р.А. 02.03.05 … 1
… 01.03.05 … 2
… 04.03.05 … 3
.
.
.
30
Программа 17.3:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define DL_FIO 25 /* длина поля фамилии в файле */
#define DL_DATA 9 /* длина поля даты поступления */
#define DL_DIAG 40 /* макс. длина диагноза */
struct pacient /* структура записи входного файла */
{ char fio [DL_FIO]; /* фамилия и инициалы пациента */
char data [DL_DATA]; /* дата поступления */
char diag [DL_DIAG+2]; /* диагноз + '\n' + '\0' */
};
/*---------------------------*/
/* главная функция */
/*---------------------------*/
int main()
{ int tab [31] = {0}; /* таблица с прямым доступом */
FILE *f; /* ссылка на входной файл */
struct pacient tz; /* текущая запись файла */
int m; /* номер заданного месяца */
int i; /* индекс элемента таблицы */
clrscr();
f= fopen("patient.txt", "r");
if (f==NULL)
{ puts ("Файл patient.txt не найден");
getch();
return 1;
}
printf ("Введите номер месяца:");
scanf ("%d",&m);
if (m<1 || m>12)
{ puts ("Неверный номер месяца");
getch();
return 2;
}
/* Чтение файла и заполнение таблицы */
while (fgets((char *)&tz), sizeof tz, f) )
if (atoi(&tz.data[3]) == m)
{ i = atoi (tz.data) - 1;
tab[i]++;
}
/* Печать таблицы */
{ int n =0; /* число ненулевых элементов в таблице */
for (i=0; i<31; i++)
if (tab[i] !=0)
{ if (n==0) { puts ("День Число пациентов");
puts ("-------------------------------");
}
n++;
printf ("%d \t %d \n", i+1, tab[i]);
}
if (n == 0) puts ("Нет пациентов, поступивших в заданном месяце");
}
getch();
return 0;
}