Как выйти из рекурсии 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 просмотр