Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Teoretichni_osnovi_programuvannya.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
132.61 Кб
Скачать

Теоретичні основи програмування

1. Комбінаторні алгоритми обробки структур даних. Задачі пошуку та сортування.

Під сортуванням розуміється перегрупування елементів у структурі так, щоб вони утворили впорядковану за зростанням чи спаданням послідовність. Оскільки масиви розміщені у швидкій внутрішній оперативній пам’яті, яка при програмуванні має обмеження на розмір, то всі алгоритми сортування масивів називається внутрішніми алгоритмами сортування. Вони використовують прямий доступ до довільного елемента масиву за його індексованим номером. Оскільки структури даних у вигляді файлів розміщуються у достатньо повільній зовнішній пам’яті і мають практично не обмежений розмір, то всі алгоритми сортування файлів називаються зовнішніми (використовує послідовний доступ до елементів файлу) або алгоритмами сортування послідовностей. Існують прямі та швидкі методи.

У прямих методах за 1 етап 1 елемент переміщається на своє місце у структурі, інші елементи практично не перегруповуються(складність порядку ).

Швидкі методи за 1 етап окрім переміщення 1 елемента на своє місце, суттєво перегруповують між собою решту елементів( ).

Однією з найпоширеніших задач обробки структур даних є пошук. Найчастіше таку задачу застосовують до однорідних структур. Це, в першу чергу, масиви, рядки символів, файли як типізовані, так і текстові. Під пошуком розуміється встановлення факту входження деякого елементу, або послідовності елементів у структуру даних та визначення індексного номеру початку входження у структуру. Якщо ж шуканого елемента немає, то алгоритм повинен дати негативну відповідь.

Серед задач пошуку виділяють 2 підзадачі:

- пошук першого входження елемента чи послідовності;

- пошук всіх входжень елемента чи послідовності.

В останньому випадку можна розглядати повторюване виконання задачі пошуку першого входження, але із зміщенням початкової позиції пошуку на наступний елемент у стуктурі після останнього знайденого. Оскільки пошук фрагмента чи підпослідовності передбачає співставлення всіх елементів шуканої підпослідовності з елементами заданої структури даних, то алгоритмічно ця задача є складнішою і відділеною від задачі пошуку даного елемента.

2. Алгоритми пошуку елемента в масиві за даними критеріями. Прямий і бінарний пошук.

Під пошуком розуміється послідовність дій, необхідних для визначення позиції входження елемента із певним значенням в деякій сукупності даних. Припускається, що група даних, в якій необхідно відшукати заданий ключ, є фіксована, а всі елементи певним чином впорядковані. Не обмежуючи загальності вважатимемо, що множина N елементів деякого абстрактного типу basetype задана у вигляді масиву

a : array [1..N] of basetype.

Прямий пошук рядка.

Часто доводиться зустрічатися із специфічним пошуком - так званим пошуком рядка. Мається на увазі визначення позиції в одній послідовності елементів, починаючи з якої інша послідовність повністю в неї входить. Така операція часто зустрічається в задачах обробки текстів.

Нехай задано масив a із N елементів та масив b із M елементів, які називаються відповідно базовим рядком та підрядком або образом, причому :

a : array [1..N] of basetype ; b : array [1..M] of basetype ;

Пошук рядка передбачає встановлення першого входження образа b в базовий рядок a.

Прямий пошук полягає в повторюваному порівнянні елементів двох масивів. У випадку неспівпадання чергової пари елементів образ зсувається на одну позицію вздовж базового масиву і процес порівняння проводиться знову починаючи з першого елемента шуканого підрядка.

Процес порівняння елементів може припинитися при виконанні однієї із двох умов:

1) всі елементи образа співпали з відповідними елементами бази – це означає, що позиція входження встановлена ;

2) після чергового неспівпадання елементів та зсуву образа відбувся вихід підрядка за межі бази – це означає, що шуканий підрядок не входить в базовий.

Якщо позначити положення початку образа відносно бази через індекс k, а біжучий індекс по образу – через j, то ці умови можна записати у вигляді диз’юнкції логічних виразів (j>M) or (k>N-M+1). Позначимо також біжучий індекс порівнюваних елементів бази через i.

Таким чином програмна реалізація прямого пошуку підрядка в рядку матиме вигляд процедури :

Var i, j, k : integer;

Begin

j:=1; k:=1;

while (j<=M) and (k<=N-M+1) do

begin

j:=1; i:=k;

while (j<=M) and (a[i]=b[j]) do

begin i:=i+1; j:=j+1 end;

k:=k+1

end;

if j>M then writeln ('номер позицiї·входження', k-1)

else writeln ('не має входження образу в базу’);

End.

Пошук діленням пополам (бінарний пошук).

Очевидно, що ніякого іншого способу підвищення ефективності пошуку в масиві не має, якщо відсутня додаткова інформація про дані. Пошук можна значно покращити, якщо елементи в масиві попередньо будуть впорядковані.

Нехай масив a є впорядкованим по зростанню, тобто

, .

Розглядуваний алгоритм базується на таких принципах :

1) вибирається довільно деякий елемент, наприклад a m ;

2) проводиться порівняння a m з аргументом пошуку x ;

3) якщо значення співпадають, то пошук припиняється, якщо a m<x, то відкидаються з розгляду всі елементи масиву до a m включно, якщо a m>x, то відкидаються з розгляду всі елементи масиву після a m включно.

Такий процес послідовного вибору та порівняння елемента із шуканим ключем продовжується поки або не буде встановлено входження в масив, або не залишиться жодного елемента для вибору, тобто входження не має.

Введемо наступні позначення : L, R - індексні змінні, що відмічають відповідно лівий і правий кінці частини масиву, де ще можна знайти потрібний елемент. Алгоритм такого пошуку можна записати у вигляді послідовності команд :

L:=1; R:=N; f:=true;

while (L<=R) and f do

begin

m:=k; {k - довільне значення між L і R}

if a[m]=x then f:=false else

if a[m]<x then L:=m+1 else R:=m-1

end;

Очевидно, що вибір m може бути довільним. Однак найкраще - відкидати на кожному кроці, незалежно від результату порівняння, якомога більше елементів.

Оптимальним є вибір серединного елемента в розглядуваній частині, оскільки завжди рівноімовірно відкидатиметься половина масиву. В результаті максимальна кількість порівнянь округлює число log(N) до найближчого цілого. Це значно краще від лінійного пошуку (середня кількість порівнянь - N/2).

Однак, можна ще покращити ефективність, якщо спростити умову припинення алгоритму. Для цього необхідно відмовитися від бажання припинення пошуку при фіксації співпадання. Тоді пошук продовжуватиметься доти, доки досліджувана частина масиву не стягнеться до одного елемента, який і буде шуканим :

L:=1; R:=N;

while L<R do

begin

m:=(L+R) div 2;

if a[m]<x then L:=m+1 else R:=m

end;

Умова припинення циклу L>=R досягається. Адже для цілочисельного серединного значення m справедлива нерівність L<=m<R, якщо попередньо виконувалася умова L<R. Отже, або L збільшується при присвоєнні йому значення m+1, або R зменшується при присвоєнні йому значення m. Таким чином, різниця R-L на кожному кроці зменшується, і при досягненні нульового значення (L=R) повторення циклу припиняється.

Варто зауважити, що виконання умови L=R ще не гарантує знаходження потрібного ключа. Потрібно враховувати, що елемент a[R] в порівнянні ніколи участі не бере.Тому необхідна додаткова перевірка після циклу на рівність a[R]=x.

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