Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование4172 / Лекции / Лекция 17. Таблицы.doc
Скачиваний:
49
Добавлен:
12.03.2015
Размер:
115.2 Кб
Скачать

Лекция 16. Таблицы

Таблицы

Таблица – это набор элементов, содержащих ключ – отличительный признак для поиска элементов, и тело – сопутствующую информацию.

Примеры таблиц.

  1. Таблица функции f(x): ключ – аргумент x, тело – значение f(x).

  2. Словарь: ключ – слово, тело – его перевод.

  3. Таблица имен компилятора: ключ – имя объекта программы (например, переменной), тело – его характеристики (тип, адрес, значение и т.п.).

Таблицы используются везде, где есть поиск информации.

Основные операции над таблицами

  1. Инициализация (подготовка к работе).

  2. Поиск элемента по ключу – основная операция (входит в другие операции).

  3. Включение в таблицу данного элемента.

  4. Исключение из таблицы элемента с данным ключом.

  5. Изменение в таблице тела элемента с данным ключом.

  6. Распечатка элементов таблицы в порядке, определяемом ключами.

  7. Сортировка таблицы по возрастанию или убыванию ключей.

Типы таблиц

- статическая (постоянная) и динамическая (меняющаяся при выполнении программы);

- внутренняя (в ОП) и внешняя (во внешней памяти, в файле);

- последовательная, с прямым доступом, древовидная.

Последовательные таблицы

Последовательной (линейной) называют таблицу, в которой производится линейный поиск, т.е. последовательный перебор элементов с начала таблицы.

Последовательные таблицы бывают сортированными и несортированными. Внутренние таблицы могут храниться в виде вектора или в виде списка. Рассмотрим операции над таблицами на примерах.

Пример 17.1.

Задача. Дана последовательность слов, разделенных пробелами или символов перевода строки. Конец последовательности отмечается нажатием клавиш Ctrl – Z (конец файла). Подсчитать количество повторений каждого слова в последовательности. Результат вывести в алфавитном порядке.

Например, исходная последовательность:

май апрель май июнь июль

август май апрель

Результат:

Слово Количество

-------------------------------------------------

август 1

апрель 2

июль 1

июнь 1

май 3

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

Метод решения. Очередное введенное слово ищется в таблице. Если его там нет, оно включается в таблицу, если есть, увеличивается число его повторений.

Будут использоваться все основные операции над таблицами, кроме исключения элемента.

Алгоритм 1. Использование последовательной несортированной таблицы в виде вектора.

  1. Чтение слов и заполнение таблицы.

  2. Сортировка таблицы по алфавиту.

  3. Печать таблицы.

май

1

май

1

апрель

1

май

2

апрель

1

Пример

заполнения

таблицы:

. . .

Программа 17.1:

#include <stdio.h>

#include <string.h>

#include <conio.h>

#define DSLMAX 21 /* макс. длина слова + 1 (‘\0’) */

#define DTMAX 30 /* макс. длина таблицы (макс. число разных слов) */

/* тип элемента таблицы */

struct EL_TAB

{ char sl [DSLMAX]; /* слово */

int kol; /* количество повторений */

};

/* прототипы функций */

void CorrectTab (struct EL_TAB tab[], int *dt, char tsl[]);

void SortTab (struct EL_TAB tab[], int dt);

/*----------------------------*/

/* главная функция */

/*----------------------------*/

int main()

{ struct EL_TAB tab[DTMAX]; /* таблица слов */

int dt=0; /* длина таблицы (число элементов) */

int i; /* индекс тек. элемента таблицы */

char tsl [DSLMAX]; /* текущее слово */

/*------------------------------------------------------------*/

/* 1. Чтение слов и заполнение таблицы */

puts ("\n\n Введите последовательность слов");

while (scanf("%s", tsl)!=EOF)

CorrectTab(tab, &dt, tsl); /* корректировка таблицы для прочитанного

слова */

/*------------------------------------------------------------*/

/* 2. Сортировка таблицы по алфавиту */

SortTab (tab, dt);

/*-------------------------------------------------------------*/

/* 3. Печать таблицы */ puts ("\n\n Слово Кол-во");

puts (" -------------------------");

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

printf(" %-*s %d\n", DSLMAX, tab[i].sl, tab[i].kol);

getch();

}

/*-------------------------------------------------------------------------------*/

/* Функция корректировки таблицы для прочитанного слова */

/*-------------------------------------------------------------------------------*/

void CorrectTab (struct EL_TAB tab[], int *dt, char tsl[])

/* Вх. данные: tab – таблица слов, */

/* *dt – длина таблицы, */

/* tsl – текущее слово */

/* Вых. данные: tab, *dt */

{ int i; /* индекс очередного элемента таблицы */

/* линейный поиск текущего слова в таблице */ for (i=0; i<*dt && strcmp(tsl,tab[i].sl); i++);

if (i<*dt) /* слово найдено */

tab[i].kol++; /* увеличение количества повторений слова */

else /* слова нет в таблице */

if (*dt < DTMAX) /* есть место в таблице */

{ strcpy(tab[i].sl,tsl); /* запись слова в конец таблицы */

tab[i].kol=1;

(*dt)++;

}

else { printf("\n Таблица переполнена.");

printf (" Слово %s не учитывается.", tsl);

}

}

/*-------------------------------------------------------------------*/

/* Функция сортировки таблицы слов по алфавиту */

/*-------------------------------------------------------------------*/

void SortTab (struct EL_TAB tab[], int dt)

{ int k,i; /* параметры циклов */

struct EL_TAB s; /* вспомогательная переменная для перестановки элементов таблицы */

for (k=dt -1; k>0; k--)

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

if (strcmp(tab[i].sl, tab[i+1].sl)>0)

{ /* перестановка эл-тов tab[i] и tab[i+1] */

s = tab[i];

tab[i] = tab[i+1];

tab[i+1] = s;

}

}

Алгоритм 2. Использование последовательной сортированной таблицы в виде списка.

Первый элемент таблицы можно сделать фиктивным с пустым словом, чтобы включение нового слова в начало таблицы происходило так же, как и в середину таблицы (упростить операцию включения).

После чтения очередного слова оно ищется в списке. Если слово есть в списке, значение поля количества kol увеличивается на 1. Если его там нет, то создается новый элемент списка, в него записывается слово и количество 1, а затем этот элемент включается в соответствующее место списка так, чтобы не нарушить алфавитный порядок слов. Поэтому сортировка таблицы не нужна (в отличие от предыдущего алгоритма).

Алгоритм:

  1. Инициализация таблицы – создание таблицы из одного фиктивного элемента.

  2. Чтение слов и формирование таблицы в виде списка.

  3. Печать таблицы.

  4. Удаление таблицы (освобождение памяти).

Программа 17.2:

#include <stdio.h>

#include <string.h>

#include <conio.h>

#include <stdlib.h>

#define DSLMAX 21 /* макс. длина слова + 1 (‘\0’) */

/* тип элемента таблицы */

struct EL_TAB

{ char sl [DSLMAX]; /* слово */

int kol; /* количество повторений */

struct EL_TAB *sled; /* указатель на следующий элемент */

};

/* прототипы функций */

void CorrectTab (struct EL_TAB *pt, char tsl[]);

void UdalTab(struct EL_TAB *pt);

/*----------------------------*/

/* главная функция */

/*----------------------------*/

int main()

{ struct EL_TAB *pt; /* указатель таблицы (ссылается на фиктивный эл-т) */

struct EL_TAB *i; /* указатель текущего эл-та таблицы (при печати) */

char tsl [DSLMAX]; /* текущее слово */

/*--------------------------------------------------------------*/

/* 1. Инициализация таблицы */

pt = (struct EL_TAB *) malloc (sizeof (struct EL_TAB));

pt->sled = NULL;

strcpy (pt->sl,"");

/*--------------------------------------------------------------*/

/* 2. Чтение слов и формирование таблицы в виде списка */

puts ("\n\n Введите последовательность слов ");

while (scanf("%s",tsl)!=EOF)

CorrectTab (pt, tsl); /* корректировка таблицы для прочитанного слова */

/*--------------------------------------------------------------*/

/* 3. Печать таблицы */

puts ("\n\n Слово Кол-во");

puts (" -------------------------");

for (i=pt->sled; i; i=i->sled)

printf (" %-*s %d\n", DSLMAX, i->sl, i->kol);

getch();

/*--------------------------------------------------------------*/

/* 4. Удаление таблицы */

UdalTab (pt);

}

/*-------------------------------------------------------------------------------*/

/* Функция корректировки таблицы для прочитанного слова */

/*-------------------------------------------------------------------------------*/

void CorrectTab(struct EL_TAB *pt, char tsl[])

/* Вх. данные: pt - указатель начала таблицы, */

/* tsl - текущее слово */

{ struct EL_TAB *i, *j, *k; /* указатели элементов таблицы */

/* линейный поиск текущего слова в таблице */ j = pt;

while ( j && strcmp (tsl,j->sl)>0)

{ k=j; j=j->sled; }

if ( j && strcmp (tsl,j->sl) == 0 ) /* слово найдено */

j->kol++;

else /* слова в таблице нет */

{ /* создание нового элемента */

i = malloc (sizeof (struct EL_TAB));

strcpy (i->sl,tsl);

i->kol = 1;

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

k->sled = i;

i->sled = j;

}

}

/*-----------------------------------------*/

/* Функция удаления таблицы */

/*-----------------------------------------*/

void UdalTab (struct EL_TAB *pt)

{ struct EL_TAB *i;

while (pt)

{ i=pt;

pt = i->sled;

free (i);

}

}