Сейчас на форуме: hgdagon, asfa, bartolomeo (+4 невидимых)

 eXeL@B —› Программирование —› Рекурсии в паскале
Посл.ответ Сообщение

Ранг: 25.8 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 26 января 2007 04:31
· Личное сообщение · #1

Я решил задачу на паскале. Условие задачи:
Ф-ция f(n) для целых неотрицательных n определена так: f(0)=0, f(1)=1, f(2n)=f(n), f(2n+1)=f(n)+f(n+1).
Для данного N найти и напечатать f(n).

Вот моя прога:

program zadacha;
var
a:integer;
function f(n:integer):integer;
begin
If n=0 then f:=0;
if n=1 then f:=1;
If odd(n) then f:=f(n div 2)
else f:=f(n div 2)+f((n div 2)+1)
end;
begin
Write('Vvedite chislo: '); readln(a);
write('f(a)=',f(a));
readln
end.

Проблема в выделенной строке: С этой строкой при компиляции выдаётся ошибка: "stack overflow error".
Если эту строку убрать, то прога нормально компилируется, но эта строка обязана быть здесь. Без неё никак.
Подскажите пожалуйста, что это за ошибка и как от неё избавиться, а то как только я начинаю делать прогу с рекурсией, такая фигня вылетает... Помогите плз..




Ранг: 353.0 (мудрец)
Активность: 0.370
Статус: Участник
resreveR

Создано: 26 января 2007 04:39
· Личное сообщение · #2

[poly] glot пишет:
Проблема в выделенной строке: С этой строкой при компиляции выдаётся ошибка: "stack overflow error".

не помню что там с паскалем..но имхо рекусрия получается ооочень вложенная..сделай размер стэка побольше...а лучше как нибудь переписать функу

-----
Тут не могла быть ваша реклама





Ранг: 155.4 (ветеран)
Активность: 0.140
Статус: Участник
Робо-Алкаш

Создано: 26 января 2007 04:49
· Личное сообщение · #3

Максимальный размер стека.. 65кб, что связано с тогдашней сегментацией..
тоесть тоесть если у тебя 33000 тысячи коэффициент вложенности приблизительно максимальное количество.. если тебе нужен именно пример для лабы.. тогда проверяй каждый раз.. значение вложенности.. (глобальная переменная).. коряво, но ведь и сам Паскаль корявый.. хотя надо приучать себя к правильности кодирования..

-----
Researcher




Ранг: 36.1 (посетитель)
Активность: 0.010
Статус: Участник

Создано: 26 января 2007 09:56
· Личное сообщение · #4

Дело не в размере стека, а в неправильности описания функции. Я здесь вижу 2 причины
1. функция odd - проверка на НЕ четность, т.е. если n=2, odd(2)=false и f(2)=f(1)+f(2) <- здесь и зациклится.
2. после первых 2-х проверок должен быть выход из процедуры (f-то уже нашли), а у тебя опять его вычисление <- опять зацыклится.
Поэтому делаем так:

function f(n:integer):integer;
begin
If n=0 then f:=0 else
if n=1 then f:=1 else
If not (odd(n)) then f:=f(n div 2)
else f:=f(n div 2)+f((n div 2)+1)
end;
должно работать..



Ранг: 25.8 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 26 января 2007 10:30
· Личное сообщение · #5

Спасибо Malice, даже не представляешь, как ты меня выручил...
(А я-то всю жизнь думал, что odd - проверка на чётность...:s14



Ранг: 36.1 (посетитель)
Активность: 0.010
Статус: Участник

Создано: 26 января 2007 11:49
· Личное сообщение · #6

Обращайся, это я еще помню
overwriter пишет:
но ведь и сам Паскаль корявый

С чего это? Не бывает корявых языков, бывают кривые програмописатели..




Ранг: 120.9 (ветеран), 5thx
Активность: 0.080
Статус: Участник
Programmer and reverser

Создано: 26 января 2007 12:03
· Личное сообщение · #7

Malice пишет:
бывают кривые програмописатели

не кривые, а криворукие) и не обижай человека!
[poly] glot
в паскале есть директива компилятора, которой задается максимальный размер стека.

-----
Уважайте других и пишите грамотно.




Ранг: 36.1 (посетитель)
Активность: 0.010
Статус: Участник

Создано: 26 января 2007 13:02
· Личное сообщение · #8

Executioner пишет:
не кривые, а криворукие) и не обижай человека!

Сорри, если кто не так понял.. Я имел ввиду, что не надо на паскаль бочку катить, язык как язык..


 eXeL@B —› Программирование —› Рекурсии в паскале
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати