Методические указания студенту к лабораторной работе по теме

advertisement
Методические указания студенту к лабораторной работе по теме
«Парадигмы и языки программирования»
Ниже приведены четыре возможных подхода к написанию алгоритма «быстрой сортировки» на четырёх разных
языках программирования. Справа от каждого блока кода приведено его краткое описание. Также обязательно
нужно ознакомиться с полными версиями этих программ, которые раздал преподаватель.
Для более детальных справок по синтаксису языков, а также по более глубоким аспектам различных парадигм
программирования, рекомендуется воспользоваться свободно доступной в интернете информацией.
Императивный процедурный подход (на примере языка C)
void swap(int i, int j) {
int t = x[i];
x[i] = x[j];
x[j] = t;
}
Процедура quicksort принимает два целых числа —
минимальный l и максимальный u индексы в глобальном
массиве x, который нужно отсортировать в этом диапазоне.
void quicksort(int l, int u) {
int i, m;
if(l >= u) return;
swap(l, randint(l, u));
m = l;
for(i = l+1; i <= u; i++)
if(x[i] < x[l])
swap(++m, i);
swap(l, m);
quicksort(l, m-1);
quicksort(m+1, u);
}
Её работа заключается в следующем: выбирается случайным
образом из нашего диапазона число, ставится на первую
позицию. Потом последовательным сравнением в начало
массива попадают все числа меньше него. После них идёт наше
сравниваемое число, а дальше до конца массива идут
оставшиеся числа, те, которые больше нашего числа. После
этого эти две половинки массива (с мéньшими числами и с
бóльшими) по отдельности сортируются таким же образом.
Императивный объектно-ориентированный подход (на примере языка C#)
public class SortableArray {
private int[] x;
public SortableArray(int[] values) {
x = values;
}
public void Sort() {
quickSort(0, x.Length - 1);
}
public int[] Values {
get {
return x;
}
}
private void swap(int i, int j) {
int t = x[i];
x[i] = x[j];
x[j] = t;
}
private void quickSort(int l, int u) {
int i, m;
if (l >= u) return;
swap(l, new Random().Next(l, u + 1));
m = l;
for (i = l + 1; i <= u; i++)
if (x[i] < x[l])
swap(++m, i);
swap(l, m);
quickSort(l, m - 1);
quickSort(m + 1, u);
}
Сердце этого кода, по большому счёту, такое же, как в
предыдущем примере. Но здесь из разряда глобальных
переменных сортируемый массив x перешёл в приватные
переменные класса, также детальная реализация quickSort()
скрыта за публичным методом Sort().
Конструктор класса инициализирует массив x переданными ему
значениями, публичное свойство Values позволяет
воспользоваться результатами сортировки извне, метод Sort()
просто вызывает сортировку всего массива.
}
1
Декларативный функциональный подход (на примере языка Haskell)
quicksort [] = []
quicksort (p:aaa) =
quicksort [ y | y <- aaa, y < p ] ++
[p] ++
quicksort [ y | y <- aaa, y >= p ]
Посмотрим, как реализована функция сортировки списка
quicksort построчно. В первой строке мы указываем, что
отсортированный пустой список — это пустой список. Это
условие нужно для предотвращения бесконечной рекурсии.
В последней строчке кода мы пишем, что для остальных случаев
мы воспринимаем переданный список как первый элемент p и
все остальные элементы aaa, а результат сортировки склеиваем
из отсортированных y, где y берутся из aaa, притом только
такие, чтобы были меньше p; самого p; а также отсортированных
элементов списка больше или равных p.
Декларативный логический подход (на примере языка Prolog)
quicksort([X|Xs],Ys) :partition(Xs,X,Left,Right),
quicksort(Left,Ls),
quicksort(Right,Rs),
appendLists(Ls,[X|Rs],Ys).
quicksort([],[]).
partition([X|Xs],P,[X|Ls],Rs) :X =< P, partition(Xs,P,Ls,Rs).
partition([X|Xs],P,Ls,[X|Rs]) :X > P, partition(Xs,P,Ls,Rs).
partition([],P,[],[]).
Правило quicksort чем-то похоже на аналогичную функцию из
предыдущего примера. Только оно в первую очередь разделяет
по правилу partition первым элементом остаток списка на две
половинки — Left и Right, содержащие числа меньше
сравниваемого числа и больше него, соответственно. Эти
половинки сортируются по отдельности, а после чего
склеиваются в результирующий отсортированный список Ys.
appendLists([],Ys,Ys).
appendLists([X|Xs],Ys,[X|Zs]) :appendLists(Xs,Ys,Zs).
Источники
Бесплатно скачать GNU Prolog можно с сайта http://www.gprolog.org, а интерпретатор Hugs 98 для Haskell можно
загрузить с сайта http://haskell.org/hugs. Доступных инструментов для работы с языками C и C# можно найти
довольно много. В частности, для первого можно воспользоваться Dev-Cpp, для второго подойдёт стандартный
компилятор csc.exe в составе .NET Framework.
Самостоятельная работа
1. Ознакомиться с работой вышеприведённых программ «вживую», вставляя в исходный код программы
данные из файлов «dataN.txt».
a. В системе Hugs файл открывается командой :load “<Путь к файлу>\quicksort.hs”, после чего
пишется название вызываемой функции — main.
b. В GNU Prolog файл открывается командой consult(“<Путь к файлу>\quicksort.pro”). (точка
обязательна)
c. В остальных средах способ загрузки файла зависит от того, какой продукт вы используете,
обычно программу требуется скомпилировать и запустить.
2. Написать на этих четырёх языках программирования процедуру/класс/функцию/правило, позволяющее
подсчитать, сколько раз в заданном массиве встречается искомое число. Выдержать программу в
рамках своей парадигмы. На C реализовать программу в рамках двух подходов: в императивном
процедурном и декларативном функциональном.
3. Запустить написанные программы с исходными данными из файлов, в соответствии со своим вариантом.
2
Вариант
I
II
III
IV
V
VI
VII
VIII
IX
X
Файл
data1.txt
data2.txt
data3.txt
data4.txt
data5.txt
data1.txt
data2.txt
data3.txt
data4.txt
data5.txt
Число
1
2
3
4
5
6
7
8
9
10
4. Сообщить преподавателю получившийся ответ и подготовить к устной защите пять исходных файлов,
выполненных по заданию.
Что нужно знать






Понимать принципы работы «быстрой сортировки» и её реализаций в примерах.
Понимать и уметь объяснять собственный код.
Понимать, чем отличается императивный подход от декларативного.
Уметь определять признаки процедурного, объектно-ориентированного, функционального и
логического программирования.
Знать и понимать основные принципы ООП.
Уметь строить рекурсивные алгоритмы.
3
Download