Помогите мне перевести обычную дробь в десятичную ...вот кое что есть.
var ar:array[1..2000]of integer; a,c,d,b:longint; begin readln(a);readln(b); repeat inc(d); if a>b then begin ar[d]:=a div b; a:=a mod b; end; a:=a*10; until (a=0) or (d=2000); for c:=1 to 2000 do write(ar[c]); end; end.
но эта прога не определяет место запятой и если есть повторяющиеся числа после запятой то их не записывает в таком виде:
1/3=0.(3) 2/3=0.(6) 1/7=0.(142857) и т.д
Большое спс за ранее...
Автор: klem4 16.03.2007 13:23
Как вариант, переводить число в троку, и искать есть ли после запятой постоянно повторяющиеся последовательности. Сначала смотреть есть ли постоянное посторение первого символа, если нет, первых двух, если нет, первых трех и так далее до длины length(s) div 2, где s содержит только дробную часть.
добавлено
Только пожалуй немного сложнее, придется сделать еще один цикл, с какого символа от начала начинать искать повторения, ведь наверное возможны случаи 1.487(3)
Lapp наверное об этом сечас пишет ?))
не угадал
Автор: Lapp 16.03.2007 14:13
Запятую ставить просто.. Сначала выводишь первый элемент массива, за ним ставишь запятую, а потом все остальные (начиная со второго в цикле). А вот отслеживать период - это посложнее.. Не обязательно переводить в строку, можно отслеживать момент, когда переменная a повторится.
И еще - у тебя ошибочка. Знак > замени на >=.
Добавлено через 4 мин.
Цитата(klem4 @ 16.03.2007 9:23)
Lapp наверное об этом сечас пишет ?))
не угадал
сколько программистов - столько и подходов! Интересно бы устроить решение задачи (несложной), но не показывать до некоторого времени, а потом сравнить..
Автор: arximed 16.03.2007 16:51
var ar:array[1..2000]of integer; a,c,d,b:longint; begin readln(a);readln(b); repeat inc(d); if a>b then begin ar[d]:=a div b; a:=a mod b; end; a:=a*10; until (a=0) or (d=2000); for c:=1 to 2000 do begin if c=2 then write('.'); write(ar[c]); end; end; end.
Спасибо за помощь ...проблему с запятой я уже решил но с повторениями ни как не могу разобраться...
Автор: volvo 16.03.2007 17:37
arximed, я бы делал так: сначала находим для дроби период вот по этому алгоритму: http://algolist.manual.ru/maths/teornum/findperiod.php
А вот потом начинается самое интересное: при заполнении массива Ar просто просматриваем последние N заполненных ячеек (где N = длине периода), и если их содержимое совпадает с самим периодом - то все, заканчиваем цикл, и распечатываем значения...
Программу для проверки этого способа я написал, конечно, ее не покажу, но способ работает. Вот результаты прогона для дробей 1/7, 1/3, 2/3, 2/7, 7/30 и 3/8 соответственно (сначала печатается только период, а потом- результат):
Начал писать прогу - volvo как всегда опередил... Спасибо ему за ссылку, если бы я раньше выложил, код был бы неправильный!
Цитата(volvo @ 16.03.2007 13:37)
и если их содержимое совпадает с самим периодом - то все, заканчиваем цикл, и распечатываем значения...
Вот этого я не понял... Я делал так - сравнивал последний полученный остаток со всеми остальными, полученными ранее - если совпадает, то найдена периодичность. Вот код:
var c :integer; {целая часть от деления} m :array [0..count] of integer; {остатки от делений} d :array [1..count] of shortint; {массив цифр после запятой} i,j,k :integer; {индексы} f :boolean; {найдена ли повторяемость}
begin {clrscr;} c := a div b; m[0] :=a mod b;
i:=0; j:=0; f:=false; while (i<count) and (not f) do {находим последовательно все цифры после запятой} begin {пока не найдена последовательность} inc(i); d[i] := (m[i-1]*10) div b; {находим очередную цифру} m[i] := (m[i-1]*10) mod b; {и остаток} if m[i]=0 then break; {дальше идут одни нули искать нечего} j:=i; {сравниваем остатки от делений начиная с конца} while (j>0) and (not f) do begin dec(j); f := (m[j] = m[i]); { совпадает!!! } end; end;
write(c:0,'.'); {выводим целую часть и точку} if f then {если нашли} begin for k:=1 to j do write(d[k]:0); {выводим то, что не повторяется} write('('); for k:=j+1 to i do write(d[k]:0); {выводим то, что повторяется} writeln(')'); end else begin for k:=1 to i do write(d[k]:0); {выводит все} writeln; end;
readkey; end.
Автор: volvo 16.03.2007 19:20
Цитата
Вот этого я не понял...
Я вот так делал:
Спойлер(Показать/Скрыть)
const p = 10;
var ar: array[1 .. 2000] of integer; a, c, d, b: longint;
period: string; i, j, k, m, n: integer; found: boolean;
begin // readln(a);readln(b); a := 7; b := 30;
period := ''; m := a; n := b; k := 1; while(k <= n) or (j <> m) do begin
if k = n then j := m; i := p*m div n; m := p*m mod n; if k >= n then begin period := period + chr(ord('0') + i); end; inc(k);
end; writeln(period);
repeat inc(d); if a>b then begin ar[d]:=a div b; a:=a mod b;
if period <> '0' then begin
found := true; for i := 1 to length(period) do begin if d - i + 1 > 0 then begin if chr(ar[d - i + 1] + ord('0')) <> period[length(period) - i + 1] then begin found := false; break; end end else found := false; end;
if found then begin dec(d, length(period)); break; end;
end; end; a := a * p; until (a = 0) or (d = 2000);
for c := 1 to d do begin
write(ar[c]); if c = 1 then write('.');
end; if found then writeln('(' + period + ')');
end.
Автор: arximed 16.03.2007 21:01
Volvo,извини но я не понял что твоя прога вычисляетjava script:add_smilie(":!4:","smid_46")?почему что не вводишь она всегда выдает 3 и 2.(3)?
Автор: volvo 16.03.2007 21:14
А ты убери строку
a := 7; b := 30;
, иначе у тебя всегда будет вычисляться 7/30, независимо, от того, что ты введешь...
Автор: hiv 16.03.2007 21:20
Цитата(volvo @ 16.03.2007 15:20)
Я вот так делал:
Теперь понял. Твой код эффективней.
Автор: arximed 16.03.2007 21:23
Цитата(volvo @ 16.03.2007 18:14)
А ты убери строку
a := 7; b := 30;
, иначе у тебя всегда будет вычисляться 7/30, независимо, от того, что ты введешь...