Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Strukturi_danikh_ta_algoritmi_-_konspekt_lektsi...doc
Скачиваний:
33
Добавлен:
23.11.2019
Размер:
870.4 Кб
Скачать

3.3.Метод інтерполяції

Я кщо немає ніякої додаткової інформації про значення ключів, крім факту їхнього впорядкування, то можна припустити, що значення key збільшуються від a[0] до a[N-1] більш-менш „рівномірно”. Це означає, що значення середнього елементу a[N / 2] буде близьким до середнього арифметичного між найбільшим та найменшим значенням. Але, якщо шукане значення key відрізняється від вказаного, то є деякий сенс для перевірки брати не середній елемент, а „середньо-пропорційний”, тобто такий, номер якого пропорційний значенню key:

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

int BinSearch(int *a, int key)

{

int b, e, i;

b = 0; e = N-1; // початкові значення меж

while ( b < e ) // цикл, поки інтервал пошуку не звузиться до 0

{

i = b + (key – a[b])*(e-b) / (a[e] – a[b]);

if ( a[i] == key )

return i; // ключ знайдений - повернення індексу

else

if ( a[i] < key )

b = i + 1; // пошук в правому підінтервалі

else

e = i - 1; // пошук в лівому підінтервалі

}

return -1; // ключ не знайдений

}

Вираз для поточного значення i одержано з пропорційності відрізків на рисунку:

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

3.4.Метод „золотого перерізу”

Деякий ефект дає використання так званого „золотого перерізу”. Це число , що має властивість:

Доданій корінь і є золотим перерізом.

Згідно цього алгоритму відрізок be слід ділити не навпіл, як у бінарному алгоритмі, а на відрізки, пропорційні та 1, в залежності від того, до якого краю ближче key. Замість оператора

i = …;

у програму бінарного пошуку слід внести наступний фрагмент, попередньо визначивши константу Phi:

if a[e] - key < key - a[b]

i = b + (e - b) * (Phi - 1);

else

i = e - (e - b) * (Phi - 1) + 1;

3.5.Алгоритми пошуку послідовностей

Даний клас задача відноситься до задачі пошуку слів у тексті. Нехай масив a[N] вважається масивом символів останній елемент якого – 0:

char a[N];

у якому слід знайти заданий рядок символів: довжиною m.

3.5.1.Прямий алгоритм пошуку

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

i = 0; // номер символу масиву a

while (i < N - lenghts)

{

j = 0; // номер символу рядка s

while ((s[j] == a[i+j]) && (j<lenghts)

j++;

if (j==lenghts)

return i; // успіх

}

Якщо збіги відбуватимуться досить часто, то час роботи програми може бути досить значним.

Існує варіант удосконалення цього алгоритму – це починати пошук після часткового збігу не з наступного елементу масиву, а з символу, наступного після тих, що переглядалися, якщо у рядку s немає фрагментів, що повторюються.

j = 0; // j - номер символа у a

found = false;

while (!found)

{

i = 0; // i - номер символа у s

while ((s[i] == a[j]) && (s[i] != ‘/0’)

{

i++;

j++;

};

if (s[i] == ‘/0’

found = true;

else

j -= i-1;

};

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