- •Алгоритмы и алгоритмические языки
- •Лекция 1 Представление чисел в эвм Целые
- •Вещественные
- •Ошибки вычислений
- •Лекция 2 Алгоритмы. Сведение алгоритмов. Нижние и верхние оценки.
- •Сортировки Постановка задачи
- •Сортировка пузырьком.
- •Сортировка слиянием с рекурсией.
- •Сортировка слиянием без рекурсии.
- •Лекция 3 Алгоритмы. Сведение алгоритмов. Сортировки и связанные с ними задачи.
- •Доказательство корректности работы алгоритма.
- •Оценки времени работы алгоритма.
- •Некоторые задачи, сводящиеся к сортировке.
- •Лекция 4 Алгоритмы. Сведение алгоритмов. Сортировки и связанные с ними задачи.
- •HeapSort или сортировка с помощью пирамиды.
- •Алгоритмы сортировки за время o(n)
- •Сортировка подсчетом
- •Цифровая сортировка
- •Сортировка вычерпыванием
- •Лекция 5 Алгоритмы. Сведение алгоритмов.
- •Порядковые статистики.
- •Поиск порядковой статистики за время (n) в среднем
- •Поиск порядковой статистики за время (n) в худшем случае
- •Язык программирования c.
- •Переменные
- •Структуры данных.
- •Вектор.
- •Лекция 6
- •Стек. Реализация 1 (на основе массива).
- •Стек. Реализация 2 (на основе массива с использованием общей структуры).
- •Стек. Реализация 3 (на основе указателей).
- •Стек. Реализация 4 (на основе массива из двух указателей).
- •Стек. Реализация 5 (на основе указателя на указатель).
- •Очередь.
- •Стандартная ссылочная реализация списков
- •Ссылочная реализация списков с фиктивным элементом
- •Реализация l2-списка на основе двух стеков
- •Реализация l2-списка с обеспечением выделения/освобождения памяти
- •Лекция 7 Структуры данных. Графы.
- •Поиск пути в графе с наименьшим количеством промежуточных вершин
- •Представление графа в памяти эвм
- •Массив ребер
- •Матрица смежности
- •Матрица инцидентности
- •Списки смежных вершин
- •Реберный список с двойными связями (для плоской укладки планарных графов)
- •Лекция 8 Структуры данных. Графы.
- •Поиск кратчайшего пути в графе
- •Алгоритм Дейкстры
- •Конец вечного цикла
- •Алгоритм Дейкстры модифицированный
- •Конец вечного цикла
- •Лекция 9 Бинарные деревья поиска
- •Поиск элемента в дереве
- •Добавление элемента в дерево
- •Поиск минимального и максимального элемента в дереве
- •Удаление элемента из дерева
- •Поиск следующего/предыдущего элемента в дереве
- •Слияние двух деревьев
- •Разбиение дерева по разбивающему элементу
- •Сбалансированные и идеально сбалансированные бинарные деревья поиска
- •Операции с идеально сбалансированным деревом
- •Операции со сбалансированным деревом
- •Поиск элемента в дереве
- •Добавление элемента в дерево
- •Удаление элемента из дерева
- •Поиск минимального и максимального элемента в дереве
- •Поиск следующего/предыдущего элемента в дереве
- •Слияние двух деревьев
- •Разбиение дерева по разбивающему элементу
- •Лекция 10 Красно-черные деревья
- •Отступление на тему языка с. Поля структур.
- •Отступление на тему языка с. Бинарные операции.
- •Высота красно-черного дерева
- •Добавление элемента в красно-черное дерево
- •Однопроходное добавление элемента в красно-черное дерево
- •Удаление элемента из красно-черного дерева
- •Лекция 11
- •Высота b-дерева
- •Поиск вершины в b-дереве
- •Отступление на тему языка с. Быстрый поиск и сортировка в языке с
- •Добавление вершины в b-дерево
- •Удаление вершины из b-дерева
- •Лекция 12 Хеширование
- •Метод многих списков
- •Метод линейных проб
- •Метод цепочек
- •Лекция 14 Поиск строк
- •Отступление на тему языка с. Ввод-вывод строк из файла
- •Алгоритм поиска подстроки с использованием хеш-функции (Алгоритм Рабина-Карпа)
- •Конечные автоматы
- •Отступление на тему языка с. Работа со строками
- •Алгоритм поиска подстроки, основанный на конечных автоматах
- •Лекция 15 Алгоритм поиска подстроки Кнута-Морриса-Пратта (на основе префикс-функции)
- •Алгоритм поиска подстроки Бойера-Мура (на основе стоп-символов/безопасных суффиксов)
- •Эвристика стоп-символа
- •Эвристика безопасного суффикса
- •Форматы bmp и rle
- •Bmp без сжатия.
Лекция 1 Представление чисел в эвм Целые
Беззнаковые целые.
Используется двоичное представление чисел.
x = an-1*2n-1 + an-2*2n-2 + … a1*21 + a0*20
здесь каждый член ai представляет собой 0 или 1 или, иначе говоря, одну цифру в двоичном представлении данных.
n задается количеством бит (в одном бите хранится одна двоичная цифра), отводящихся под данное число.
BCD - Binary Coded Decimal
В одном байте хранятся две цифры десятичного представления. Применяется, например, в СУБД Oracle для хранения вещественных чисел с плавающей точкой.
Целые со знаком.
Существует три основных формата:
-
прямой (старший бит служит признаком знака: 1=’-‘; 0=’+’)
-
обратный (для представления отрицательного числа берется представление его модуля, а потом все биты инвертируются)
-
дополнительный (для представления отрицательного числа берется представление его модуля, все биты инвертируются, к результату прибавляется 1)
Реально, в основном, используется только дополнительный код.
Утверждение 1. Представление чисел в дополнительном коде эквивалентно представлению чисел в кольце вычетов по модулю 2n, где n – количество бит в двоичном представлении числа.
Следствие. Операции сложения, вычитания и умножения корректно производятся независимо от способа интерпретации целых чисел – дополнительного кода (для знакового целого) или беззнакового целого.
Вещественные
Вещественные числа с фиксированной запятой.
VB тип Currency - восьмибайтовая переменная, которая содержит вещественное число в формате с фиксированной десятичной запятой (четыре десятичных знака после запятой).
C# тип decimal
Вещественные числа с плавающей запятой.
Формат закреплен IEEE: Institute of Electrical and Electronics Engineers.
Число представляется в виде
x = s * m * 2d
где
s – знак (отводится один бит)
m – мантисса в виде 1.xxxxx (где x – двоичная цифра; 1 не хранится)
d – степень (оставшиеся биты)
Согласно формату IEEE вместо степени хранится характеристика = d-dmin , где dmin – минимально возможное значение мантиссы. Таким образом, минимально возможное значение характеристики = 0.
На самом деле, по стандарту IEEE представление более сложное. Пока характеристика положительна поддерживается вышеуказанное представление. Для нулевой характеристики число хранится уже как число с фиксированное запятой в виде
x = p * 2-dmin
где p – число с фиксированной точкой в виде x.xxxxx (где x – двоичная цифра; хранятся все указанные биты!).
Таким образом, отрицательные степени двойки будут иметь битовое представление (степень выделена пробелами):
2-122: 1.88079e-037: 0 00000101 00000000000000000000000
2-123: 9.40395e-038: 0 00000100 00000000000000000000000
2-124: 4.70198e-038: 0 00000011 00000000000000000000000
2-125: 2.35099e-038: 0 00000010 00000000000000000000000
2-126: 1.17549e-038: 0 00000001 00000000000000000000000
2-127: 5.87747e-039: 0 00000000 10000000000000000000000
2-128: 2.93874e-039: 0 00000000 01000000000000000000000
2-129: 1.46937e-039: 0 00000000 00100000000000000000000
2-130: 7.34684e-040: 0 00000000 00010000000000000000000
2-131: 3.67342e-040: 0 00000000 00001000000000000000000
2-132: 1.83671e-040: 0 00000000 00000100000000000000000
2-133: 9.18355e-041: 0 00000000 00000010000000000000000
2-134: 4.59177e-041: 0 00000000 00000001000000000000000
2-135: 2.29589e-041: 0 00000000 00000000100000000000000
2-136: 1.14794e-041: 0 00000000 00000000010000000000000
…
2-148: 5.73972e-042: 0 00000000 00000000000000000000010
2-149: 2.86986e-042: 0 00000000 00000000000000000000001
2-150: 1.43493e-042: 0 00000000 00000000000000000000000
Т.е. число 2-150 уже неотличимо от 0.Если вышеуказанные число получались каждый раз путем деления предыдущего числа на 2, то в результате получения последнего число из 2-149 мы получили ситуацию underflow – нижнее переполнение. Как правило, процессоры могут отслеживать underflow, но нижнее переполнение можно расценивать как ошибку, а можно и не расценивать, ведь при многих вычислениях слишком маленькие числа можно расценивать как нулевые. Поэтому, обычно никаких сообщений в ситуации underflow не производится.
Переполнение при увеличении чисел называется overflow. При увеличении чисел с плавающей точкой степень увеличивается до максимально возможной. Когда степень достигает максимально возможного значения, то подобное число уже числом не считается, независимо от значения бит мантиссы:
2-118: 3.32307e+035: 0 11110101 00000000000000000000000
2-119: 6.64614e+035: 0 11110110 00000000000000000000000
2-120: 1.32923e+036: 0 11110111 00000000000000000000000
2-121: 2.65846e+036: 0 11111000 00000000000000000000000
2-122: 5.31691e+036: 0 11111001 00000000000000000000000
2-123: 1.06338e+037: 0 11111010 00000000000000000000000
2-124: 2.12676e+037: 0 11111011 00000000000000000000000
2-125: 4.25353e+037: 0 11111100 00000000000000000000000
2-126: 8.50706e+037: 0 11111101 00000000000000000000000
2-127: 1.70141e+038: 0 11111110 00000000000000000000000
2-128: 1.#INF : 0 11111111 00000000000000000000000
2-129: 1.#INF : 0 11111111 00000000000000000000000
2-130: 1.#INF : 0 11111111 00000000000000000000000
Итак, стандартом IEEE закреплено наличие дополнительных констант:
NAN – not a number. Не число = 0/0 [ (0111 1111)(1100 0000) 0…0]
+INF – плюс бесконечность [ (0111 1111)(1000 0000) 0…0]
-INF – минус бесконечность [ (1111 1111)(1000 0000) 0…0]
+0 = 0x00 00 00 00
-0 = 0x80 00 00 00
+INF, -INF,+0, -0 можно корректно сравнивать. +0 = = -0 = = 0.
NAN при сравнении возвращает ложь всегда кроме !=. В этом случае возвращается истина.
Для IBM PC:
float (32bit)
1bit – знак
8bits – степень+127 (127=27-1)
23bits – символы xxxxx из мантиссы (мантисса в виде 1.xxxxxx)
пример 1.f=
0 = знак
01111111 = степень+127 (занимает 8 бит)
0000…0 = символы xxxxx из мантиссы (мантисса в виде 1.xxxxxx)
Итого: 00111111 10000000 00000000 00000000
Осталось заметить, что байты идут в обратном порядке (также и в последующих примерах).
doudle (64bit)
1bit – знак
11bits – степень+210-1
42bits – символы xxxxx из мантиссы (мантисса в виде 1.xxxxxx)
пример 1.f=
00111111 11110000 00000000 00000000 00000000 00000000 00000000 00000000
long double (80bit)
1bit – знак
15bits – степень+214-1
64bits – символы 1xxxxx из мантиссы (мантисса в виде 1.xxxxxx)
В некоторых версиях языка С тип long double присутствует, но является всего лишь синонимом типа double.