Форум «Всё о Паскале» _ Задачи _ рекурсивное деление
Автор: maksimla 8.11.2009 18:04
Придположим что купили компиютер,который невыполняет натуральных чисел деления операцию. Задание. Напишите рекурсированную процедуру двух натуральных чисел деление остатка и (ой забыл слово) найти тоесть выполняющяя операцию div и mod.
Сделал я это все только нерекурсивно просто в процедуре написал
program Bevarde0; var a,b,m,c:integer; procedure del (a,b:integer); begin m:=0; while a>=b do begin inc(m); a:=a-b; end; c:=a; end; begin WriteLn('iveskite du skaicius'); readln(a,b); del(a,b); writeln(a,' div ',b,' = ',m); writeln(a,' mod ',b,' = ',c); readln; end.
Можете обьяснить как мне сделать рекурсией только невыкладываете решение то я сам хочю сделать рекурсией.
Добавлено через 16 мин. Вот что получилось у меня рекурсивно
procedure del (a,b:integer); begin m:=-1; if a>=b then del(a-b,b); inc(m); writeln('m= ',m); if m=0 then c:=a; end;
кажется что все нормально выводит но мне кажется что както можно лутшей может обьясните но только невыкладывайте решения
Автор: volvo 8.11.2009 18:22
Цитата
Можете обьяснить как мне сделать рекурсией
Любую рекурсивную подпрограмму надо начинать писать с условия, которое ее прекратит. То есть, когда прекратятся рекурсивные вызовы, и начнется "раскрутка в обратную сторону". Иначе очень просто получить "Переполнение стека", запустив рекурсию бесконечную...
В твоем случае этим условием может быть A < B, тогда сам процесс деления можно считать законченным, и надо будет просто "собрать" информацию, чему же равно частное.
А вот если это условие не выполняется, то надо продолжать процесс деления, и вызывать опять del рекурсивно, уменьшая A...
Hint: не работай через глобальные переменные, это нехорошо. Передавай все, что тебе нужно - через параметры, а чтобы вернуть результат - делай не процедуру деления, а функцию. Если одного результата мало (а его таки мало, надо вернуть И частное И остаток), то частное вернется, как результат функции, а остаток - через Var - параметр...
Автор: maksimla 8.11.2009 18:36
вот тут у меня происходит то самое деление
procedure del (a,b:integer); begin m:=-1; if a>=b then del(a-b,b); inc(m); writeln('m= ',m); if m=0 then c:=a; end;
но мочему мне тут надо делать параметр m:=-1; и мне кажется что это if m=0 then c:=a; совсем лишнее
Цитата(volvo @ 8.11.2009 13:22)
Hint: не работай через глобальные переменные, это нехорошо. Передавай все, что тебе нужно - через параметры, а чтобы вернуть результат - делай не процедуру деления, а функцию. Если одного результата мало (а его таки мало, надо вернуть И частное И остаток), то частное вернется, как результат функции, а остаток - через Var - параметр...
неочень понял но мне ведь написали что надо сделать процедурой
Добавлено через 7 мин. вот я избавился от некоторых глобальных перемнных
program Bevarde0; var a,b,m,c:integer; procedure del (x,y:integer); begin m:=-1; if x>y then del(x-y,y); inc(m); writeln('m= ',m); if m=0 then c:=x; end; begin WriteLn('iveskite du skaicius'); readln(a,b); del(a,b); writeln(a,' div ',b,' = ',m); writeln(a,' mod ',b,' = ',c); readln; end.
вы имели в веду чтобы я в процедуре неупотреблял a,b ? и почему нехорошо пользоватся глобальными переменными
Автор: volvo 8.11.2009 18:53
Цитата
но мочему мне тут надо делать параметр m:=-1;
А кто тебе сказал, что оно действительно надо? Можно и без этого обойтись. Я ж тебе сказал, начинай делать с условия выхода, ты опять непонятно с чего начинаешь... Хочешь - покажу, как надо делать, а объяснять, почему сделано ТАК, когда сделано явно неправильно - я не буду...
Цитата
мне ведь написали что надо сделать процедурой
Ну, значит, мучайся с процедурой. Когда можно сделать проще - обычно делают проще. Я тебе уже написал, откуда это идет, и опять убеждаюсь в сказанном. Тебя сейчас мучают "делай процедурами", а потом (на другом языке) милостиво разрешат использовать функции, и ты первый будешь всем рассказывать, какой отстой этот Паскаль. Я видел уже такой финт, не надо спорить. Это очень грязные приемы, но к сожалению, они используются в некоторых местах...
Любую рекурсивную подпрограмму надо начинать писать с условия, которое ее прекратит
А ты что делаешь? У меня получилось так
function del (x,y:Integer; var i:Integer):Integer; begin if x<y then del:=x //Вот условие "выхода" else begin //А это как бы тело самой функции inc(i); //увеличили частное del:=del(x-y,y,i); //вызвали del с новыми праметрами end; end;
А в вызове 3-м параметром должна быть переменная со значением 0. Наверно можно и в рекурсии над ней поколдовать, чтоб не заботится о начальном значении переменной.
Автор: TarasBer 8.11.2009 20:56
Кстати говоря, исходная задача - реализовать деление вручную - вовсе не так надумана, как кажется. Если посмотреть, как в дельфах реализовано деление двух чисел типа int64, то окажется, что там как раз всё делится "вручную". Но там, конечно, не вычитание делается, а двоичное деление в столбик. Это я к чему. Алгоритм есть куда оптимизировать.
Автор: maksimla 8.11.2009 21:13
Цитата(Client @ 8.11.2009 15:36)
Для заметки: с рекурсией я сам не дружу А ты что делаешь?
А я так мало с чем вообще дружу. А я нечего и не сделал только ерунду и все. А я думал когда рекурсивно доходит значение
if x>y then del(x-y,y);
x<y то тогда конец
Автор: maksimla 9.11.2009 17:04
всем спасибо
Автор: buy prednisone without a prescri 2.10.2021 15:20
Canada Pacription Drugs
Автор: can i take tramadol neurontine a 8.10.2021 0:55