Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
математическая логика и теория алгоритмов.doc
Скачиваний:
120
Добавлен:
10.05.2014
Размер:
2.32 Mб
Скачать
          1. 2. Поэлементное сравнение двух строк

Алгоритм сравнения двух строк достаточно простой, поэтому далее приводится только текст функции.

struct Item{

char s;

Item *next;

};

int compare(Item *first, Item *second)

{

/* символы строк, участвующие в формировании результата сравнения */

char c1 = '\0', c2 = '\0';

while(first && second && first->s == second->s){

first = first->next;

second = second->next;

}

/* если строки не равны, тогда один или оба указателя –first и second – не пусты */

if(first) /* не пуст */

c1 = first->s;

if(second) /* не пуст */

c2 = second->s;

return c1 - c2;

}

Текст данной функции также приводится в файле stringl.cpp.

          1. 3. Разбиение строки на части

В результате разбиения строки для исходного списка создаются новые подсписки, каждый из которых определяет соответствующий фрагмент исходной строки. Исходный список сохраняется. Количество подсписков определяется тем, сколько раз в исходной строке встретился символ-разделитель (следует учитывать, что в конце исходной строки символ-разделитель может отсутствовать). Символы-разделители в подсписки не входят. Функция формирует массив указателей на выделенные подсписки и в качестве результата возвращает количество выделенных фрагментов и указатель на первый элемент массива указателей.

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

Рис. II–20

Схема алгоритма приведена на рис. II–21.

Рис. II–21

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

Текст функции приводится ниже и в файле stringl.cpp.

int split(Item *str, char fs, Item **&mas)

{

int i, cnt;

Item **pa, *ptr;

/* подсчитать количество подсписков; при подсчете учитываем, что

* последним символом в списке может быть символ-разделитель

*/

for(ptr = str, cnt = 1; ptr; ptr = ptr->next)

if(ptr->s == fs && ptr->next)

cnt++;

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

mas = new Item *[cnt];

ptr = str;

for(i = 0; i < cnt; i++){

/* сформировать указатель на очередной подсписок */

pa = mas + i;

*pa = NULL;

/* сформировать очередной подсписок */

for(; ptr && ptr->s != fs; ptr = ptr->next){

*pa = new Item;

(*pa)->s = ptr->s;

(*pa)->next = NULL;

pa = &(*pa)->next;

}

/* пропустить символ-разделитель */

if(ptr)

ptr = ptr->next;

}

return cnt;

}

          1. 4. Функция нахождения подстроки в строке

Прототип функции может иметь следующий вид:

struct Item{

char s;

Item *next;

} Item;

Item * substr(Item *string1, Item *string2);

Функция возвращает указатель на первое вхождение подстроки string2в строкуstring1илиNULL, если подстрокаstring2не входит в строкуstring1. Схема алгоритма функции приведена на рис.II–22.

Рис. II–22

Текст функции приводится ниже и в файле stringl.cpp.

struct Item{

char s;

Item *next;

} Item;

Item * substr(Item *string1, Item *string2)

{

Item *ptr1, *ptr2;

for(; string1; string1 = string1->next){

/* начинаем сравнение двух строк-списков,

* запомнив текущий символ первой строки

*/

for(ptr1 = string1, ptr2 = string2; ptr1 && ptr2;

ptr1 = ptr1->next, ptr2 = ptr2->next)

if(ptr1->s != ptr2->next)

break; /* символы не совпали –

* продолжаем просмотр первой строки */

if(!ptr2)

return string1; /* все символы строк совпали */

}

return NULL;

}

      1. Стеки

Динамическую структуру данных стек можно отображать и вектором, и списком.

Как было сказано ранее, стек характеризуется одним концом – вершиной стека. Операции занесения информации в стек и выборки из стека выполняются всегда через вершину стека. При чтении информации из стека необходимо проверять ситуацию "стек пуст"; данная ситуация представляет собой специальный случай штатной ситуации, требующий, возможно, особой обработки в программе, работающей со стеком. При записи информации, учитывая, что данные размещаются в некотором ограниченном пространстве, следует проверять ситуацию "стек полон", при которой запись в стек невозможна. Данная ситуация является нештатной и свидетельствует, как правило, о недостаточной проработке прикладной программы (или наличии ошибки в программе). Возникновение такой ситуации в программе требует анализа правильности ее функционирования и принятия необходимых мер.

Способы анализа таких ситуаций и реакции на них зависят от того, как стек отображается в оперативной памяти. Рассмотрим особенности использования каждой структуры.