Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
TA1_2.DOC
Скачиваний:
12
Добавлен:
02.11.2018
Размер:
444.42 Кб
Скачать

§ 5. Порядковые статистики Определение.

k-ым наименьшим элементом последовательности a1, a2,..., an называется такой элемент b этой последовательности, что ai < b не более чем для k-1 значений i и aib не менее чем для k значений i.

Задача. Найти k-ый наименьший элемент в n-элементной последовательности.

C пособ 0.

Упорядочить последовательность в порядке неубывания ее элементов и взять k-ый элемент. Сложность O(nlog2n). [ Л1, с.113 ]

Cпособ 1.

Алгоритм 5.1

Вход. Последовательность S из n элементов, принадлежащих линейно упорядоченному множеству, и kN, 1kn.

Выход. k-ый наименьший элемент последовательности S.

Метод. Применяется рекурсивная процедура SELECT.

S

Procedure SELECT(k, S ):

if | S | < 50 then

begin

упорядочить S;

return k-ый наименьший элемент в S

end

else

begin

разбить S на  S / 5 последовательностей по 5 элементов в каждой;

при этом останется не более четырех неиспользованных элементов;

упорядочить каждую пятиэлементную последовательность;

пусть M – последовательность медиан этих пятиэлементных множеств;

m  SELECT(  M /2 , M );

пусть S1, S2, S3 последовательности элементов из S, соответственно меньших,

равных и больших m;

if S1  k then return SELECT( k­, S1 )

else

if ( S1 + S2  k ) then return m

else return SELECT( k­ – S1 – S2 , S3 )

end

Теорема 5.2.

Алгоритм 5.1 находит k­­–ый наименьший элемент в n–элементной последовательности S за время O(n).

Корректность алгоритма доказывается индукцией по  S .

Пусть T(n) – время, затраченное на выбор k–ого наименьшего элемента из последовательности длины n. M  n/5. Следовательно, рекурсивный вызов процедуры SELECT(  M /2 , M ) занимает время, не большее T(n/5).

Покажем, что S1  3n/4 ,  S2  3n/4.

Не менее n/ 10 элементов последовательности M больше или равны m и для каждого из них найдутся в S два различных элемента, которые также соотносятся с m. Следовательно,

S1  n ­ 3 n/ 10 , т.е. при n  50 длина последовательности S1 меньше 3n/4. Аналогичное рассуждение применимо и к S3. Поэтому рекурсивный вызов в строке 10 или 12 занимает времени не более T(3n/4). Все остальные операторы тратят не более O(n) времени. Таким образом , для некоторой постоянной c

§ 6. Вхождение образца

Задача. [ Ахо, с.367]

Определить вхождение слова длины n в строку длины m.( n << m)

char str[m], x[n];

Способ 1.

k = 0; r = 0;

while ( ( str [r + k] == x [k] ) && k < n) k++ ;

if (k == n) begin

слово нашлось

end;

else {r++ ;}

Cложность O(nm).

Алгоритм начинает работу с первого символа цепочки текста str. Если str1 = x1, то рассматривается вторая позиция цепочки текста, k = 1. Если str1x1, то k = 0, r = 1.

Допустим, что после прочтения i символов k = j. Это означает, что последние j символов цепочки str1stri совпадают с x1xj, а последние s символов str1stri не являются префиксом цепочки x1xn для s > j . Если stri+1=xj+1 , то k = j+1 . Если stri+1 xj+1 , то k равно наибольшему t, такому, что x1xt - суффикс цепочки str1stri+1.

Способ 2.

Чтобы облегчить нахождение значения t , вводится функция f, принимающая целочисленные значения.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]