Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ рекурсивное деление

Автор: 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;
А кто тебе сказал, что оно действительно надо? Можно и без этого обойтись. Я ж тебе сказал, начинай делать с условия выхода, ты опять непонятно с чего начинаешь... Хочешь - покажу, как надо делать, а объяснять, почему сделано ТАК, когда сделано явно неправильно - я не буду...

Цитата
мне ведь написали что надо сделать процедурой
Ну, значит, мучайся с процедурой. Когда можно сделать проще - обычно делают проще. Я тебе уже написал, откуда это идет, и опять убеждаюсь в сказанном. Тебя сейчас мучают "делай процедурами", а потом (на другом языке) милостиво разрешат использовать функции, и ты первый будешь всем рассказывать, какой отстой этот Паскаль. Я видел уже такой финт, не надо спорить. Это очень грязные приемы, но к сожалению, они используются в некоторых местах...

Автор: maksimla 8.11.2009 20:10

у меня чегото неполучается функцией

program Bevarde0;
var a,b,m,c:integer;
function del (x,y:integer):integer;
begin
if x>y then del:=x-y-del(x-y,y);
writeln('del= ',del);
c:=x-y;
writeln©;
end;
begin
WriteLn('iveskite du skaicius');
readln(a,b);
del(a,b);
writeln(a,' div ',b,' = ',m);
writeln(a,' mod ',b,' = ',c);
readln;
end.


Автор: Client 8.11.2009 20:36

Для заметки: с рекурсией я сам не дружу smile.gif

Цитата
Любую рекурсивную подпрограмму надо начинать писать с условия, которое ее прекратит
А ты что делаешь?
У меня получилось так
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) *

Для заметки: с рекурсией я сам не дружу smile.gif А ты что делаешь?

А я так мало с чем вообще дружу. А я нечего и не сделал только ерунду и все.
А я думал когда рекурсивно доходит значение
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

Purchase Flagyl Prescription