Разбор примеров из книги
Модераторы: Oleg_D, Модераторы
Re: Разбор примеров из книги
Paster Fob » 13.09.2012 23:14:52
В целом неплохо, хотя улучшить всегда что-то можно (как предложил tema). Ещё обратите внимание на использование CONST/VAR в заголовках. Если параметр-строка внутри подпрограммы не изменяется, то лучше ставить CONST, а не VAR. В целом это повышает надёжность в крупных программах, поскольку вы не сможете ненароком испортить строку внутри процедуры.
В целом неплохо, хотя улучшить всегда что-то можно (как предложил tema). Ещё обратите внимание на использование CONST/VAR в заголовках. Если параметр-строка внутри подпрограммы не изменяется, то лучше ставить CONST, а не VAR. В целом это повышает надёжность в крупных программах, поскольку вы не сможете ненароком испортить строку внутри процедуры.
- Paster Fob
- постоялец
- Сообщения: 188
- Зарегистрирован: 22.02.2011 20:53:36
- Откуда: Новосибирск.
Re: Разбор примеров из книги
tema писал(а):Дело в том, что readln в теле процедуры не есть гуд:
Почему?
Re: Разбор примеров из книги
Paster Fob писал(а):tema писал(а):Дело в том, что readln в теле процедуры не есть гуд:
Почему?
По определению. Это же процедура. Она предполагает получение данных через параметры процедуры. Readln читает в программе переменную и передаёт процедуре через параметры.
Это не ошибка.
Re: Разбор примеров из книги
Paster Fob писал(а):tema писал(а):Дело в том, что readln в теле процедуры не есть гуд:
Почему?
Потому, что readln - это вызов процедуры, требующий вмешательства пользователя. Такие вмешательства лучше не размазывать по всей программе внутри процедур, а сконцентрировать в одном месте, лучше в главной программе.
- Paster Fob
- постоялец
- Сообщения: 188
- Зарегистрирован: 22.02.2011 20:53:36
- Откуда: Новосибирск.
Re: Разбор примеров из книги
tema писал(а):По определению. Это же процедура. Она предполагает получение данных через параметры процедуры. Readln читает в программе переменную и передаёт процедуре через параметры.
Это не ошибка.
Oleg_D писал(а):Потому, что readln - это вызов процедуры, требующий вмешательства пользователя. Такие вмешательства лучше не размазывать по всей программе внутри процедур, а сконцентрировать в одном месте, лучше в главной программе.
Ясно..
Добавлено спустя 2 минуты 12 секунд:
Вот никак не придумаю как решать следующую задачу (посчитать разность).Уже <<весь мозг сломал>>.
Re: Разбор примеров из книги
Так тем же порядком, как во 2-м классе.
Re: Разбор примеров из книги
Paster Fob писал(а):tema писал(а):Дело в том, что readln в теле процедуры не есть гуд:
Почему?
Можно ввод данных пользователя поместить в отдельную процедуру, которая и будет состоять из одних сплошных ReadLn.
- Paster Fob
- постоялец
- Сообщения: 188
- Зарегистрирован: 22.02.2011 20:53:36
- Откуда: Новосибирск.
Re: Разбор примеров из книги
Paster Fob писал(а):Вот никак не придумаю как решать следующую задачу (посчитать разность).Уже <<весь мозг сломал>>.![]()
![]()
Oleg_D писал(а):Так тем же порядком, как во 2-м классе.
Всё равно ничего не получается.При вычитании нужно из большего вычесть меньшее и при необходимости подставить или убрать -,а т.к. программа работает не с целым числом а с отдельными цифрами,то здесь и получается проблема.Нужно каким-то образом выяснить какое сверхбольшое число больше а уж потом вычислять разность.Да и с переносом не ясно как быть,здесь же надо не переносить,а наоборот занимать у старшего числа единицу.Уже пару листов A4 исписал,только конкретного ничего не получается.
Re: Разбор примеров из книги
Paster Fob писал(а):Уже пару листов A4 исписал,только конкретного ничего не получается.
Намекну, с вашего позволения:
Код: Выделить всё
_ 631 _ 345 _ 1000 или, если 1+9-4 = 6
345 631 714 познаково: 9-1 = 8
---- ---- ----- 9-7 = 2
286 -714 286
См. "дополнительный код" как представление числа.
Re: Разбор примеров из книги
Paster Fob писал(а):Вот никак не придумаю как решать следующую задачу (посчитать разность).Уже <<весь мозг сломал>>.
Вот один из вариантов решения на основе строк.
Код: Выделить всё
{ Решение к задаче 46-Б:
Вычитание двух положительных сверхбольших чисел.
Исходные числа представлены строками, содержащими только цифры.
Результат может содержать знак минус в первой позиции.
}
{ Сравнение двух ПОЛОЖИТЕЛЬНЫХ чисел
Возвращает:
1 -- arg1 > arg2
0 -- arg1 = arg2
-1 -- arg1 < arg2
}
function CompareBigNumber(const arg1, arg2 : string): integer;
var i: integer;
begin
{ Если длина разная, то большее число длиннее }
if Length(arg1) > Length(arg2)
then CompareBigNumber:=1
else if Length(arg1) < Length(arg2)
then CompareBigNumber:=-1
else begin
{ Если длина одинаковая, то сравниваем цифры, начиная со старших }
i:=1;
while (i<Length(arg1)) and (arg1[i]=arg2[i]) do Inc(i);
if Ord(arg1[i]) > Ord(arg2[i])
then CompareBigNumber:=1
else if Ord(arg1[i]) < Ord(arg2[i])
then CompareBigNumber:=-1
else CompareBigNumber:=0;
end;
end;
{ Вычитание двух ПОЛОЖИТЕЛЬНЫХ чисел }
function SubBigNumber(const arg1, arg2 : string): string;
var a, b : string;
minus : boolean;
i,d : integer;
borrow : integer; { заём }
begin
{ сравниваем числа и определяем знак }
minus:= CompareBigNumber(arg1, arg2)<0;
{ заносим уменьшаемое и вычитаемое так, что a >= b }
if minus then begin
a:= arg2; b:= arg1;
end else begin
a:= arg1; b:= arg2;
end;
{ перед вычитанием выравниваем длину }
while Length(b) < Length(a) do b:='0'+b;
borrow:= 0; { заём=0 }
{ вычитаем цифры, младшая в конце строки }
for i:= Length(a) downto 1 do begin
d:= Ord(a[i]) - Ord(b[i]) - borrow;
if d<0 then begin
d:= d+10;
borrow:= 1;
end
else borrow:= 0;
a[i]:= Chr(d + Ord('0')); { разность сохраняем в a }
end;
{ удаляем незначащие нули }
while (a[1]='0') and (Length(a)>1) do Delete(a,1,1);
{ формируем знак }
if minus then a:='-'+a;
SubBigNumber:= a;
end;
begin
Writeln(SubBigNumber('123','199'));
Writeln(SubBigNumber('199','123'));
Writeln(SubBigNumber('1000','1'));
Writeln(SubBigNumber('1','1000'));
Writeln(SubBigNumber('0','1000'));
Writeln(SubBigNumber('1000','1000'));
Readln;
end.
"В наказание" предлагаю развить задачу, распространив сложение и вычитание для чисел со знаком. То есть, и положительных, и отрицательных.
Добавлено спустя 21 минуту 1 секунду:
Ещё один вариант функции сравнения (подходит к строкам не длиннее 255)
Код: Выделить всё
function CompareBigNumber(arg1, arg2 : string): integer;
begin
{ Если длина разная, то большее число длиннее }
arg1:= Chr(Length(arg1))+ arg1;
arg1:= Chr(Length(arg2))+ arg2;
if arg1 > arg2
then CompareBigNumber:=1
else if arg1 < arg2
then CompareBigNumber:=-1
else CompareBigNumber:=0
end;
Последний раз редактировалось Oleg_D 18.09.2012 14:20:41, всего редактировалось 1 раз.
Причина: опечатка
Причина: опечатка
- Paster Fob
- постоялец
- Сообщения: 188
- Зарегистрирован: 22.02.2011 20:53:36
- Откуда: Новосибирск.
Re: Разбор примеров из книги
Во-первых я пытался решить через массивы.
Во-вторых используя строки я просто сравнивал 2 строки между собой и находил большее число.
В-третьих я не мог придумать как высчитать из меньшего большее и как занимать единицу у впереди стоящей цифры.
В-четвёртых корплю над "Наказанием".

Во-вторых используя строки я просто сравнивал 2 строки между собой и находил большее число.
Код: Выделить всё
var a,b:string;
..........
n:shortint;
begin
readln(a);
readln(b);
if a>b then n:=1
else
if a<b then n:=-1
else
n:=0;
......В-третьих я не мог придумать как высчитать из меньшего большее и как занимать единицу у впереди стоящей цифры.
В-четвёртых корплю над "Наказанием".
Re: Разбор примеров из книги
Paster Fob писал(а):В-четвёртых корплю над "Наказанием".
Тут я предлагаю взять за основу уже готовые процедуры на основе строк и поколдовать немного со знаками. В конце концов, всё сводится к тем же сложению и вычитанию.
- Paster Fob
- постоялец
- Сообщения: 188
- Зарегистрирован: 22.02.2011 20:53:36
- Откуда: Новосибирск.
Re: Разбор примеров из книги
Не могу понять почему так происходит,в чём проблема?

Код: Выделить всё
function Comparebignumber(var arg1,arg2:string):shortint;
var temp:string;
begin
if arg1>arg2 then Comparebignumber:=1
else
if arg1<arg2 then begin
Comparebignumber:=-1;
temp:=arg1;
arg1:=arg2;
arg2:=temp;
end
else
comparebignumber:=0;
end;
var st1,st2:string;
n:shortint;
begin
readln(st1);
readln(st2);
n:=comparebignumber(st1,st2);
writeln(st1);
writeln(st2);
readln
end.
Re: Разбор примеров из книги
Paster Fob писал(а):Не могу понять почему так происходит,в чём проблема?
Элементарно, Ватсон. Строки сравниваются символ за символом слева направо. Если очередной символ окажется "больше" другого, то и вся строка с этим символом считается "большей". Независимо от её длины и последующих символов. См. сравнение строк в моём варианте программ.
"45" > "1000" потому, что "4" > "1"
- Paster Fob
- постоялец
- Сообщения: 188
- Зарегистрирован: 22.02.2011 20:53:36
- Откуда: Новосибирск.
Re: Разбор примеров из книги
Ясно,я ориентировался на главу 44 где сказано про сравнение строк.В таком случае нужно добавить в книгу,ещё один пример сравнения:
И объяснить почему так.
Код: Выделить всё
Writeln ('ABC' > 'BC') {false}И объяснить почему так.
