Перейти к содержимому

Как выйти из рекурсии c

  • автор:

Как выйти из рекурсии c

Собственно возврат стоит в самом начале а она один хер пробегает все дерево ваще недогоняю почему отладчиком статус все функции бывает истина

Процедура ЗаписатьЗначениеВ_ТЗБ(ТабПараметров,Стр,Ветка,ЭтоПлан=Ложь,Ключ=»»,СтатусВсейФункции=Ложь)
Если СтатусВсейФункции Тогда
Возврат;
КонецЕсли;
СтатусФункции =Ложь;
Для Каждого Узел Из Ветка.Строки Цикл
ИдентификаторУзла= Узел.N;
НаименованиеУзла = Узел.Наименование;
ЭтоНоваяСтрока=НаименованиеУзла = «Структура бюжета ООО ‘Интерполис'»;
Если ЭтоНоваяСтрока Тогда
Попытка
Если СтатусПроверкиТекущихДанных=0 Тогда
ЗаписатьТзВотстойник(ПредИдущаяТаблица);
КонецЕсли;
Исключение
КонецПопытки;
СтатусПроверкиТекущихДанных=0;
КонецЕсли;
ПредИдущаяТаблица=ТабПараметров;
Если ИдентификаторУзла<>Неопределено ТОгда
УровеньУзла= Узел.Уровень();
ЗначениеВетки= Узел.Значение;
НаименованиеВетки=СокрЛП(Узел.Наименование);
Если не ЭтоПлан или Ключ=ИдентификаторУзла Тогда
СтатусФункции = ПроверитьЗначениеВТЗБ(Узел,УровеньУзла,ЗначениеВетки,НаименованиеВетки,ТабПараметров,Стр,ИдентификаторУзла,ЭтоПлан);
Если СтатусФункции Тогда
СтатусПроверкиТекущихДанных=СтатусПроверкиТекущихДанных+1;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ЗаписатьЗначениеВ_ТЗБ(ТабПараметров,Стр,Узел,ЭтоПлан,Ключ,СтатусФункции)
КонецЦикла;
КонецПроцедуры

а возврат происходит в первом вызове? раскрутка стэка

Как выйти из бесконечной рекурсии n=2, чтобы выводились правильные значения функции, с++

введите сюда описание изображения

Дана такая функция, коэффициенты a,b,x,y,p,q определены в коде, n — это аргумент. Для n = 1 и n = 0 код работает, выводит что нужно, но дальше нет. При n=2 будет бесконечная рекурсия, от которой нужно как-то избавиться. Помогите исправить код, чтобы выводило значение функции правильно при любых n

#include #include #include using namespace std; int a = 0, b = 0, x = 0, y = 0, p = 0, q = 0, k = 20; double F(int n) < if (n == 1) return b; if (n == 0) return a; if (n == 2) return (F(n / 2) * x) / (1 - y); if (n % 2 == 0 && n != 2) return ((F(2*n) - y * F(n + 1)) / x); if (n % 2 != 0) return ((F(2*n + 1) - q * F(n + 1)) / p); return F(n); >int main() < int n; setlocale(LC_ALL, "Russian"); a = k; b = 2*k + 1; x = 3 * k + 2; y = k * k + 2 * k - 1; p = 5 * k - 1; q = k * k + 11 * k - 3; cout > n; F(n); cout

Отслеживать
9,718 9 9 золотых знаков 24 24 серебряных знака 35 35 бронзовых знаков
задан 5 дек 2019 в 17:03
17 1 1 золотой знак 1 1 серебряный знак 3 3 бронзовых знака
А вы умеете пользоваться отладчиком ? Ваша проблема решается по щелчку пальца.
5 дек 2019 в 17:07

Вы бы функцию, раз уж она выводит неверные значения (иначе заем просить «чтобы выводило значение функции правильно при любых n»?) дли не только кодом, а все же ее математическую формулировку.

5 дек 2019 в 17:07

Да, исина где-то рядом, но я не знаю, я в программировании новичок, учусь, саму функцию добавил, сразу почему-то не получилось загрузить, правил

5 дек 2019 в 17:10
А ведь ваше решение решает совершенно другую задачу. А где ваши собственные наработки?
5 дек 2019 в 17:15

Я знаю, что после return написано не то, что должно быть, условия вроде правильные, а вот что под них написать, чтобы выйти из бесконечной рекурсии и вывести значение функции?

Как выйти из рекурсии c


Andy BitOff © ( 2009-03-18 12:12 ) [0]

Как быстро выйти из глубокой рекурсии на первый уровень?


Palladin © ( 2009-03-18 12:16 ) [1]

первый уровень должен знать, что он первый уровень, остальные — знать, что они не первый. и волшебное слово exit все решает.


KSergey © ( 2009-03-18 12:17 ) [2]

raise exception


oxffff © ( 2009-03-18 12:19 ) [3]


> Andy BitOff © (18.03.09 12:12)
> Как быстро выйти из глубокой рекурсии на первый уровень?
>

Нужно код показать.


Palladin © ( 2009-03-18 12:25 ) [4]


> KSergey © (18.03.09 12:17) [2]

и вылетишь ты из всех уровней.

Да ладно?


Palladin © ( 2009-03-18 12:39 ) [7]


> Ega23 © (18.03.09 12:36) [6]

Да. Ладно.


Andy BitOff © ( 2009-03-18 12:46 ) [8]

procedure PassingPixel(x, y: integer);
var
i: integer;
aRect: TRect;
begin
aRect := Rect(0, 0, qSource1.Width, qSource1.Height);
qDest.SetPixel(x, y, clBlack);
if DrawPixel(x, y + 1) then PassingPixel(x, y + 1);
if DrawPixel(x + 1, y + 1) then PassingPixel(x + 1, y + 1);
if DrawPixel(x + 1, y) then PassingPixel(x + 1, y);
if DrawPixel(x + 1, y — 1) then PassingPixel(x + 1, y — 1);
if DrawPixel(x, y — 1) then PassingPixel(x, y — 1);
if DrawPixel(x — 1, y — 1) then PassingPixel(x — 1, y — 1);
if DrawPixel(x — 1, y) then PassingPixel(x — 1, y);
if DrawPixel(x — 1, y + 1) then PassingPixel(x — 1, y + 1);
end;
Переопределение адреса стека не катит? Как в ассме.


> Palladin © (18.03.09 12:16) [1]

Да, я думал об этом. Это был перевый вариант, который пришел в голову, но потребуется две/три доп. переменные и дополнительные проверки.
Я просто думал, что побыстрее способ есть, который я не знаю. Такой как описал выше, например.


Skyle © ( 2009-03-18 13:06 ) [9]


> Andy BitOff © (18.03.09 12:46) [8]
> но потребуется две/три доп. переменные

Есть мнение, что потребуется один параметр. Навскидку

procedure PassingPixel(x, y: integer);
..
begin
..
if SomeCondition then raise ESomeException.Create(..);
..
end;

Так устроит ?


KSergey © ( 2009-03-18 13:14 ) [11]

> Palladin © (18.03.09 12:25) [4]
> и вылетишь ты из всех уровней.

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

А вообще у меня сильное сомнение в эффективности приведенного кода. Рекурсия — штука красивая, да, но слишком затратная, особенно если только она и присутствует, как здесь.


Кто б сомневался © ( 2009-03-18 13:15 ) [12]


> Как быстро выйти из глубокой рекурсии на первый уровень?

Неужто рекурсия настолько глубока, что break на всех уровнях займет больше секунды?


KSergey © ( 2009-03-18 13:17 ) [13]

> Кто б сомневался © (18.03.09 13:15) [12]
> Неужто рекурсия настолько глубока, что break на всех уровнях займет больше секунды?

это какой-то размер стека нужен для секунды.


PEAKTOP © ( 2009-03-18 13:20 ) [14]

> Andy BitOff © (18.03.09 12:12)
>
> Как быстро выйти из глубокой рекурсии на первый уровень?

Во-первых, закусывать — тогда не войдешь в рекурсию глубоко.

Во вторых, — бросать надо это гиблое дело, батенька.


Andy BitOff © ( 2009-03-18 13:41 ) [15]

> Сергей М. © (18.03.09 13:13) [10]
> Так устроит ?

Только в крайнем случае, т.к. выход ИЗ рекурсии, а надо вернуться на первую итерацию. Т.е., если мы вошли в рекурсию и на первом же условии «if DrawPixel(x, y + 1) then PassingPixel(x, y + 1);» ушли глубоко, то нужно выйти из этого «глубоко» на вторую проверку «if DrawPixel(x + 1, y + 1) then PassingPixel(x + 1, y + 1);».


Empleado © ( 2009-03-18 13:50 ) [16]

Может добавить счетчик?
procedure PassingPixel(x, y: integer; var RecCounter: integer);
И Exit пока не 1.


Сергей М. © ( 2009-03-18 14:22 ) [17]


> Andy BitOff © (18.03.09 13:41) [15]

Счетчик добавь, см. [16]


euru © ( 2009-03-18 15:27 ) [18]

procedure PassingPixel(x, y: Integer);
const
Counter: Integer = 0;
begin
try
inc(Counter);
. . .
if Counter > 1 then exit;
finally
dec(Counter);
end;
end;


oxffff © ( 2009-03-18 16:16 ) [19]

Я бы рекомендовал сделать так

procedure Sample;
var CurrentContex:integer;
List:TList;
RestOfTOp:integer;
begin
List:=TList.create;

while List.Count>0 do
begin
CurrentContex:=List.Items[0];
List.delete(0);
Form1.Memo1.Lines.Add(IntToStr(CurrentContex));
//Конечное условие выхода
if CurrentContex begin
List.Insert(0,CurrentContex+12);
List.Insert(0,CurrentContex+11);
List.Insert(0,CurrentContex+10);
end
else
begin
//Вот он этот выход на первый уровень
dec(RestOfTOp);
List.DeleteRange(0,List.Count-RestOfTOp);
end;
end;
List.free;
end;


oxffff © ( 2009-03-18 16:20 ) [20]


> oxffff © (18.03.09 16:16) [19]

RestOfTOp — это остаток кроны дерева первого уровня


MBo © ( 2009-03-18 16:38 ) [21]

8-связный FloodFill можно делать и нерекурсивно


Asteroid ( 2009-03-18 18:01 ) [22]


> MBo © (18.03.09 16:38) [21]
> 8-связный FloodFill можно делать и нерекурсивно

Поддерживаю 🙂
Самый быстрый выход из рекурсии — не использовать рекурсию.


Andy BitOff © ( 2009-03-18 18:22 ) [23]

> MBo © (18.03.09 16:38) [21]
> 8-связный FloodFill можно делать и нерекурсивно

TUser © (16.05.06 14:28) [11]

Оформи все это циклом. Не надо использовать рекурсию, там где не надо.

while true do begin
if DrawPixel(x, y + 1) then inc (y) else
if DrawPixel(x + 1, y) then inc (x) else
.
if . then . else
break;
end;

MBo © (16.05.06 14:47) [12]

>TUser © (16.05.06 14:28) [11]

Сэр, да вы закоренелый рекурсофоб! 😉

В выбранной парадигме без рекурсии, циклом, подобным приведенному, не обойти всю область с закоулками (ну или свой стек придется делать для возврата)

TUser © (16.05.06 14:52) [13]

Ой, я действителньо ерунду написал.


clickmaker © ( 2009-03-18 18:26 ) [24]

Halt — самый быстрый выход из рекурсии


MBo © ( 2009-03-18 21:26 ) [25]

>Старая ветка:
Думаешь, я помню подробности? 😉

А кстати, почему выбрано восьмисвязное заполнение — нужно проникать через состыкованные уголки?


Andy BitOff © ( 2009-03-18 21:34 ) [26]

> MBo © (18.03.09 21:26) [25]
> >Старая ветка:
> Думаешь, я помню подробности? 😉

Думаю нет 😉 Тем более ветка от мая 2006 =)


> А кстати, почему выбрано восьмисвязное заполнение — нужно
> проникать через состыкованные уголки?

Ну, на этой реализации, думаю, что не обязательно. Это пока еще не ясно.


MBo © ( 2009-03-18 21:39 ) [27]

Дело в том, что восьмисвязное может в нежелательные места залезть — например, пробраться сквозь наклонную однопиксельную линию. Так что использовать его стоит далеко не всегда.


Andy BitOff © ( 2009-03-18 22:10 ) [28]

Это-то я понимаю. Я просто на данном этапе не знаю какой получится результат, надо посмотреть так и так.


oxffff © ( 2009-03-18 22:40 ) [29]


> Andy BitOff © (18.03.09 22:10) [28]

[19] Смотрел?


Andy BitOff © ( 2009-03-19 12:16 ) [30]

> oxffff © (18.03.09 22:40) [29]
> [19] Смотрел?

Смотрел. Но как-то но особо понял что к чему.


oxffff © ( 2009-03-19 12:43 ) [31]


> Andy BitOff © (19.03.09 12:16) [30]
> > oxffff © (18.03.09 22:40) [29]
> > [19] Смотрел?
>
> Смотрел. Но как-то но особо понял что к чему.

А под отладчиком по шагам?


Andy BitOff © ( 2009-03-19 13:48 ) [32]

Под отладчиком не смотрел. У меня D7

Как полностью выйти из функции с рекурсией и циклом бесконечной вложенности?

Есть функция, которая с использованием рекурсии перебирает элементы массива неограниченной вложенности на соответствие определённому критерию. Обнаружив первый попавшийся элемент, соответствующий критерию, функция должна тут же вернуть 1.
Проблема в том, что из-за рекурсии, если я пишу return 1, значение возвращается в «родительскую» копию функции, и цикл продолжается. Если я пишу break 1/2/3/4 и т. д.- я завершаю лишь конкретный цикл, по вложенности относительно текущего, а у меня их может быть хоть миллион. Есть какая-то возможность скомандовать остановку всех циклов и возвращение значения 1?

Пока нашел только проверку значения возвращаемого вызванной копией — если 1, то все вложенные копии возвращают родителю 1, пока не дойдёт до самой первой.

Есть ли какое-то универсальное решение, которое останавливает самый первый цикл (break) или команда остановки самой первой копии функции (return)?

PHP 5.6, процедурный стиль.

  • Вопрос задан более трёх лет назад
  • 6541 просмотр

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *