IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

2 страниц V  1 2 >  
 Ответить  Открыть новую тему 
> бинарный поиск. поля с рекурсией.
сообщение
Сообщение #1


Пионер
**

Группа: Пользователи
Сообщений: 99
Пол: Женский
Реальное имя: vera

Репутация: -  0  +


Бинарный поиск может быть применим на одно поле, в которое элемент сортировочно внесен.
Идея бинарного поиска состоит в том, чтобы сначала рассматривать средний элемент. Если он Искомый, тогда с успехом прерываете. Если не искомый, тогда можно через сравнение искомого элемента со средним установить, нужно ли в нижней или в верхней половине поля дальше искать. При каждом неудачном шаге поиска длина исследоваемой области (досягаемости) поля делится пополам.Это ведет к логарифмеческому Run-time:
при n элементах имеется 0(ld n) Шагов поиска.
Осуществите основе типа
TYPE
IntArray = array [...] of integer
рекурсивный алгоритм:
FUNCTION Contains (a :IntArray ; left,right : integer; x : integer) :BooLean;

который в сотрированном поле а внутри области [left...right] бинарно после значения х ищет и результат TRUE возвращает, когда х в поле оказывается.
Вышеуказанная фунукция использует call by value.

не совсем понимаю задания. очень туго доходит. хотя уверена что когда 2 строчки.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Пионер
**

Группа: Пользователи
Сообщений: 99
Пол: Женский
Реальное имя: vera

Репутация: -  0  +


сам бинарные деревья в принципе понимани.
но непонятно что это за параметры левый и правый целового типа
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Профи
****

Группа: Пользователи
Сообщений: 618
Пол: Мужской

Репутация: -  24  +


Не следует путать простой бинарный поиск и бинарное дерево поиска. В твоем случае дерево строить не надо. Достаточно приведенной рекурсивной функции.

Параметры left и right - это начало и конец участка, внутри которого производится поиск. То есть сперва на место этих параметров подставляются начало и конец массива. Если элемент в середине отрезка не найден, функция должна вызвать саму себя (рекурсия), подставив на место left и right новые значения (а именно начало и конец той половины начального участка, в которой следует искать дальше).

PS Кстати, странно: в функции не предусмотрена возможность вернуть в программу найденный элемент. secret.gif


--------------------
Close the World...txeN eht nepO
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Цитата
сам бинарные деревья в принципе понимани.
А причем тут бинарные деревья? Они к бинарному поиску никакого отношения не имеют...

Задача твоя - в том, чтобы получить массив (для бинарного поиска нужно, чтобы этот массив был упорядоченным, т.е., отсортированным, иначе этот метод не работает), и в этом массиве найти заданный элемент (или не найти его, это уж как повезет). Как это делается:

1. Поскольку решение тебе надо рекурсивное - то начинаем с условия окончания (странно, правда? Но так оно и делается, с этого начинается разработка любой рекурсивной подпрограммы, иначе зациклишь ее, и даже не заметишь). Итак. Что будет условием окончания? Когда поиск должен закончиться? Все просто: Когда Right + 1 = Left, то есть, между Right и Left нет других элементов. Тогда можно считать, что мы дошли до конца, и больше рекурсия продолжаться не будет.

Если это условие:
if Right = Left + 1 then 
выполняется, то остается проверить, равен ли элемент A[ Left ] или A[ Right ] заданному. Если равен - вернуть True, если нет - вернуть False.

2. Если между индексами Left и Right есть еще элементы, то надо найти середину (среднее арифметическое), и вызывать функцию рекурсивно, вместо Right или Left подставляя значение этой середины.

Вот и все, собственно. Попробуй по написанному здесь объяснению написать код. Хотя бы его начало. Что не понятно, или не получается - говори. Задача действительно решается в несколько строк.

P.S. Поиском, значит, опять не пользуемся. Ну-ну... Потом расскажу, откуда я узнал об этом... smile.gif
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Пионер
**

Группа: Пользователи
Сообщений: 99
Пол: Женский
Реальное имя: vera

Репутация: -  0  +


Все, товарищи, спасибо. Дико ступила. стыдно
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Пионер
**

Группа: Пользователи
Сообщений: 99
Пол: Женский
Реальное имя: vera

Репутация: -  0  +


Ошибка использования BB кодов форума. Возможно вы неправильно использовали какой-то из тэгов, как, например, тэг [TAG], тогда как он должен использоваться в виде [TAG=] или наоборот.
//
Не хочет код писать/

Добавлено через 13 мин.

FUNCTION Contains (a :IntArray;l,r:integer ;x : integer) :BooLean;
VAR m: integer;
BEGIN
IF (R+1)= L
THEN
BEGIN
IF (x=a[r])or (x=a[l])THEN Contains := TRUE
ELSE
BEGIN
m := r+(l-r)div 2;
IF x=a[m] THEN Contains := TRUE
ELSE
IF x> a[m] THEN BEGIN
r := m+1;
Contains := Contains(a,l,r,x)
END
ELSE BEGIN
l := middle-1;
Contains := Contains(a,l,r,x)
END;
END;
END;



Добавлено через 52 сек.
пришлось сократить\
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Пионер
**

Группа: Пользователи
Сообщений: 99
Пол: Женский
Реальное имя: vera

Репутация: -  0  +


Не. не правильно..
вот кое-что изменила:

FUNCTION Contains (a :IntArray;l,r:integer ;x : integer) :BooLean;
VAR M: integer;
BEGIN
IF (R+1)= L THEN
BEGIN
IF (x=a[r])or (x=a[l])THEN Contains := TRUE
ELSE Contains := FALSE
END
ELSE
BEGIN
m := r+(l-r)div 2;
IF x=a[m] THEN Contains := TRUE
ELSE BEGIN
IF x> a[m] THEN BEGIN
r := m+1;
Contains := Contains(a,l,r,x)
END
ELSE BEGIN
l := m-1;
Contains := Contains(a,l,r,x)
END;

END;
END;


l = left
r = right
m = middle
И еще почему в dev pascal ругается что overloaded identifier Contains isn't a function
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Профи
****

Группа: Пользователи
Сообщений: 618
Пол: Мужской

Репутация: -  24  +


И все-таки неправильно. Покажи целиком программу, в которой ты тестируешь эту функцию. Заодно будет проще понять, почему dev pascal ругается =)

Добавлено через 4 мин.
Первое, что бросилось в глаза:
IF (R+1)= L THEN
Путаешь право и лево. Так ты никогда из рекурсии не выйдешь.

Добавлено через 15 мин.
Ух, да у тебя по всей программе так. Но даже если поменять их местами, твой алгоритм порой выходит за границы исходного интервала. Например, на следующих исходных данных:
. . .
var
Arr: array[1..3] of Integer = (1, 2, 4);
begin
Contains(Arr, 1, 3, 6);
end.


--------------------
Close the World...txeN eht nepO
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Пионер
**

Группа: Пользователи
Сообщений: 99
Пол: Женский
Реальное имя: vera

Репутация: -  0  +


Archon, честно говоря не совсем понимаю о чем ты unsure.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Профи
****

Группа: Пользователи
Сообщений: 618
Пол: Мужской

Репутация: -  24  +


Ну смотри:
L - это же Left (левая граница интервала), верно?
R - тогда соответственно Right (правая граница).
То есть L < R. Тогда как R + 1 может равняться L?


--------------------
Close the World...txeN eht nepO
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Пионер
**

Группа: Пользователи
Сообщений: 99
Пол: Женский
Реальное имя: vera

Репутация: -  0  +


аха, это поняла...наоборот

Добавлено через 1 мин.
поняла. счас исправлю..действительно по всей программе то же самое

Добавлено через 2 мин.
А с остальным что не так? unsure.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Профи
****

Группа: Пользователи
Сообщений: 618
Пол: Мужской

Репутация: -  24  +


А ты проверь с приведенным выше массивом. Там всего 3 элемента - можно и в уме сделать.


--------------------
Close the World...txeN eht nepO
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Пионер
**

Группа: Пользователи
Сообщений: 99
Пол: Женский
Реальное имя: vera

Репутация: -  0  +


все равно не понимаю/
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Профи
****

Группа: Пользователи
Сообщений: 618
Пол: Мужской

Репутация: -  24  +


На приведенных мной исходных данных функция из рекурсии никогда не выйдет. Если в уме не получается, запусти программу и убедись.

Добавлено через 4 мин.
И вообще будет выход за границы массива.


--------------------
Close the World...txeN eht nepO
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Пионер
**

Группа: Пользователи
Сообщений: 99
Пол: Женский
Реальное имя: vera

Репутация: -  0  +


это я уже поняла...
тогда нужно поставить условие

while left<= right do


вроде
я запуталась/

Добавлено через 7 мин.
и нифига это тогда не рекурсия получется
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Пионер
**

Группа: Пользователи
Сообщений: 99
Пол: Женский
Реальное имя: vera

Репутация: -  0  +


алилуя...
или очередное заблуждение или просвет :

FUNCTION Contains (a :IntArray;l,r:integer ;x : integer) :BooLean;
VAR M: integer;
BEGIN
IF l <> r THEN
BEGIN
m := l+(r-l)div 2;
IF x=a[m] THEN Contains := TRUE
ELSE BEGIN
IF x> a[m] THEN BEGIN
l := m+1;
Contains := Contains(a,l,r,x)
END
ELSE BEGIN
r := m-1;
Contains := Contains(a,l,r,x)
END;
END;
END
ELSE
BEGIN
IF (x=a[r])or (x=a[l])THEN contains := TRUE ELSE contains := FALSE
END

END;

 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Профи
****

Группа: Пользователи
Сообщений: 618
Пол: Мужской

Репутация: -  24  +


Ну, не совсем =) Лучше было бы так сделать:
FUNCTION Contains (a :IntArray;l,r:integer ;x : integer) :BooLean;
VAR M: integer;
BEGIN
IF (l+1) = r THEN
BEGIN
IF (x=a[r])or (x=a[l])THEN Contains := TRUE
ELSE Contains := FALSE;
END
ELSE
BEGIN
m := l+(r-l)div 2;
{ Проверку x=a[m] тоже убрал, так как на следющем шаге рекурсии этот }
{ элемент станет границей и все равно проверится }
IF x> a[m] THEN BEGIN
l := m; { Тут убрал "+1" }
Contains := Contains(a,l,r,x)
END
ELSE BEGIN
r := m; { Тут убрал "-1" }
Contains := Contains(a,l,r,x)
END;
END
END;
Сравни со своей старой версией.

Но это один из вариантов решения: тот, который описал volvo. Если брать строго тот алгоритм, что приведен в задании, получится так:
function Contains (a: IntArray; l, r: Integer; x: Integer): Boolean;
var
m: Integer;
begin
if l > r then
Contains := False
else begin
m := l + (r - l) div 2;
if x = a[m] then
Contains := True
else if x < a[m] then
Contains := Contains(a, l, m - 1, x)
else
Contains := Contains(a, m + 1, r, x);
end;
end;
Ищи отличия smile.gif


--------------------
Close the World...txeN eht nepO
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Гость






Цитата
    IF (l+1) = r THEN
BEGIN
IF (x=a[r])or (x=a[l])THEN Contains := TRUE
ELSE Contains := FALSE;
END
лучше заменить на
if L + 1 = R then
Contains := (x=a[R]) or (x=a[L])
, вместо включения еще одного условия...

Цитата
И еще почему в dev pascal ругается что overloaded identifier Contains isn't a function
Dev-Pascal это оболочка. Компилятор, который там используется (если я не ошибаюсь, давно его использовал) - FPC. В каком режиме совместимости ты компилируешь программу, что у тебя возникает такая ошибка (и заодно - какая версия компилятора? Вполне возможно, что тебе надо ее просто обновить)? Ты часом не пытаешься эту функцию в модуле (в Unit-е, в смысле) описывать?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #19


Пионер
**

Группа: Пользователи
Сообщений: 99
Пол: Женский
Реальное имя: vera

Репутация: -  0  +


Цитата(volvo @ 21.01.2010 19:50) *

Dev-Pascal это оболочка. Компилятор, который там используется (если я не ошибаюсь, давно его использовал) - FPC. В каком режиме совместимости ты компилируешь программу, что у тебя возникает такая ошибка (и заодно - какая версия компилятора? Вполне возможно, что тебе надо ее просто обновить)? Ты часом не пытаешься эту функцию в модуле (в Unit-е, в смысле) описывать?

1.9.2.
неа. не в модуле.


Добавлено через 4 мин.
а по поводу совместимости не знаю что сказать/
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #20


Гость






Цитата
1.9.2.
blink.gif Уже 2.2.4 на дворе... Ты б скачала новую версию FPC, и прямо там бы работала, зачем тебе этот DevPascal нужен?
 К началу страницы 
+ Ответить 

2 страниц V  1 2 >
 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 20.04.2024 17:54
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name