Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ГОСЫ / ГОСБилеты.odt
Скачиваний:
161
Добавлен:
05.06.2015
Размер:
1.54 Mб
Скачать

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

include <stdio.h>

#include <stdlib.h>

#define MyType int

//Будем считать, что ключ в нашем случае - это эзначение типа int.

//Хранение значений -в виде двоичного однонаправленного дерева. Левое поддерево - данные, со значением ключа меньше, чем вершина, прваое - большим, чем вершина.

typedef struct element //элемент-вершина дерева.

{

int key;

struct element * left_el;

struct element * right_el;

MyType val;

} MyElement;

typedef struct

{

MyElement * tree_root; //корень;

int size;

} MyMap; //сама структура хранилища.

MyMap initNewMap()

{

MyMap mm;

mm.tree_root=NULL;

mm.size=0;

return mm;

}

int add_element(MyMap * mm, int k, MyType el) //добавить пару ключ-значение

{

MyElement * new_el = malloc(sizeof(MyElement));

if(new_el)

{

new_el->key=k;

new_el->val=el;

new_el->left_el=NULL;

new_el->right_el=NULL;

if(mm->tree_root==NULL)

{

mm->tree_root=new_el;

mm->size++;

return 0;

}

if(!paste_element(new_el, mm->tree_root))

{

mm->size++;

//printf("SIZE: %d \n", mm->size);

return 0;

}

else

{

printf("ERROR!\n");

}

}

else

{

return -1;

}

}

int paste_element(MyElement * me, MyElement * root) //рекурсивная функция вставки. 0 - в случае успеха, -1 - ошибка

{

if(root==NULL)

{

return -1;

}

if(me->key==root->key)

{

root->val=me->val;

return 0;

//printf("ALREADY EXIST!\n"); //Значиение с совпадающим ключем заменяет текущее

}

if(me->key<root->key)

{

if(root->left_el==NULL)

{

//printf("ADD LEFT!\n");

root->left_el=me;

return 0;

}

else

root=root->left_el;

}

if(me->key>root->key)

{

if(root->right_el==NULL)

{

//printf("ADD Right!\n");

root->right_el=me;

return 0;

}

else

root=root->right_el;

}

paste_element(me, root);

}

MyType get_value(MyMap *mm, int key)

{

return find_element(key, mm->tree_root);

}

MyType find_element(int key, MyElement * root)

{

if(root==NULL)

{

return -1;

}

if(key==root->key)

return root->val;

else

{

if(key<root->key)

{

if(root->left_el==NULL)

{

return -1;

}

else

root=root->left_el;

}

if(key>root->key)

{

if(root->right_el==NULL)

{

return -1;

}

else

root=root->right_el;

}

find_element(key, root);

}

}

int main(void)

{

MyMap m_map = initNewMap();

add_element(&m_map, 12, 13);

add_element(&m_map, 15, 14);

add_element(&m_map, 14, 16);

add_element(&m_map, 15, 12);

add_element(&m_map, 19, 123);

add_element(&m_map, 39, 121);

printf ("VALUE 15: %d\n",get_value(&m_map, 15));

printf ("VALUE 19: %d\n",get_value(&m_map, 19));

printf ("VALUE 12: %d\n",get_value(&m_map, 12));

printf ("VALUE 12: %d\n",get_value(&m_map, 552));

return 0;

}

Билет 4.

1. Нормальный алгоритм Маркова.

Норма́льный алгори́тм Ма́ркова (НАМ) — один из стандартных способов формального определения понятия алгоритма. Понятие нормального алгоритма введено А. А. Марковым в конце 1940-х годов. Традиционно, когда говорят об алгоритмах Маркова, используют слово «алгорифм».

Нормальный алгоритм описывает метод переписывания строк, похожий по способу задания на формальные грамматики. НАМ является Тьюринг-полным языком, что делает его по выразительной силе эквивалентным машине Тьюринга и следовательно современным языкам программирования. ( про машину Тьюринга лучше не упоминать, чтобы не было дополнительных вопросов, но в курсе дела надо быть).

На основе НАМ был создан функциональный язык программирования Рефал.

Нормальные алгоритмы являются вербальными, то есть предназначенными для применения к словам в различных алфавитах. Определение всякого нормального алгоритма состоит из двух частей: определения алфавита алгоритма (к словам из символов которого алгоритм будет применяться) и определения его схемы. Схемой нормального алгоритма называется конечный упорядоченный набор т. н. формул подстановки, каждая из которых может быть простой или заключительной. Простыми формулами подстановки называются слова вида , гдеL и D — два произвольных слова в алфавите алгоритма (называемые, соответственно, левой и правой частями формулы подстановки). Аналогично, заключительными формулами подстановки называются слова вида , гдеL и D — два произвольных слова в алфавите алгоритма. При этом предполагается, что вспомогательные буквы ине принадлежат алфавиту алгоритма (в противном случае на исполняемую ими роль разделителя левой и правой частей следует избрать другие две буквы).

Примером схемы нормального алгоритма в пятибуквенном алфавите | * abc может служить схема

Процесс применения нормального алгоритма к произвольному слову V в алфавите этого алгорифма представляет собой дискретную последовательность элементарных шагов, состоящих в следующем. Пусть V' — слово, полученное на предыдущем шаге работы алгорифма (или исходное слово V, если текущий шаг является первым). Если среди формул подстановки нет такой, левая часть которой входила бы в V', то работа алгоритма считается завершённой, и результатом этой работы считается слово V'. Иначе среди формул подстановки, левая часть которых входит в V', выбирается самая верхняя. Если эта формула подстановки имеет вид , то из всех возможных представлений словаV' в виде RLS выбирается такое, при котором R — самое короткое, после чего работа алгоритма считается завершённой с результатом RDS. Если же эта формула подстановки имеет вид , то из всех возможных представлений словаV' в виде RLS выбирается такое, при котором R — самое короткое, после чего слово RDSсчитается результатом текущего шага, подлежащим дальнейшей переработке на следующем шаге.

Например, в ходе процесса применения алгорифма с указанной выше схемой к слову | * | | последовательно возникают слова | b * | , ba | * | , a | * | , a | b * , aba | * , baa | * , aa | * ,aa | caacac | и c | | , после чего алгорифм завершает работу с результатом | | . Другие примеры смотрите ниже.

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

Пример

Данный алгоритм преобразует двоичные числа в «единичные», то есть на выходе получается строка из N единичек, если на входе у нас было N в двоичной системе. Например, 101 преобразуется в 5 единиц:

Правила:

«|0» → "0||"

«1» → "0|"

«0» → "" (пустая строка)

Исходная строка:

«101»

Выполнение:

«0|01»

«00||1»

"00||0|"

"00|0|||"

"000|||||"

"00|||||"

"0|||||"

"|||||"

Соседние файлы в папке ГОСЫ