Разбор примеров из книги

Книга адресована школьникам средних и старших классов, желающим испытать себя в «олимпийских схватках». Может быть полезна студентам-первокурсникам и преподавателям информатики.

Модераторы: Oleg_D, Модераторы

Re: Разбор примеров из книги

Сообщение Oleg_D » 14.09.2012 09:19:29

Paster Fob » 13.09.2012 23:14:52
В целом неплохо, хотя улучшить всегда что-то можно (как предложил tema). Ещё обратите внимание на использование CONST/VAR в заголовках. Если параметр-строка внутри подпрограммы не изменяется, то лучше ставить CONST, а не VAR. В целом это повышает надёжность в крупных программах, поскольку вы не сможете ненароком испортить строку внутри процедуры.
Oleg_D
постоялец
 
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

Re: Разбор примеров из книги

Сообщение Paster Fob » 14.09.2012 10:11:00

tema писал(а):Дело в том, что readln в теле процедуры не есть гуд:

Почему?
Аватара пользователя
Paster Fob
постоялец
 
Сообщения: 188
Зарегистрирован: 22.02.2011 21:53:36
Откуда: Новосибирск.

Re: Разбор примеров из книги

Сообщение tema » 14.09.2012 10:21:05

Paster Fob писал(а):
tema писал(а):Дело в том, что readln в теле процедуры не есть гуд:

Почему?

По определению. Это же процедура. Она предполагает получение данных через параметры процедуры. Readln читает в программе переменную и передаёт процедуре через параметры.
Это не ошибка.
tema
постоялец
 
Сообщения: 375
Зарегистрирован: 24.03.2011 20:19:27

Re: Разбор примеров из книги

Сообщение Oleg_D » 14.09.2012 10:49:33

Paster Fob писал(а):
tema писал(а):Дело в том, что readln в теле процедуры не есть гуд:

Почему?

Потому, что readln - это вызов процедуры, требующий вмешательства пользователя. Такие вмешательства лучше не размазывать по всей программе внутри процедур, а сконцентрировать в одном месте, лучше в главной программе.
Oleg_D
постоялец
 
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

Re: Разбор примеров из книги

Сообщение Paster Fob » 14.09.2012 10:51:43

tema писал(а):По определению. Это же процедура. Она предполагает получение данных через параметры процедуры. Readln читает в программе переменную и передаёт процедуре через параметры.
Это не ошибка.

Oleg_D писал(а):Потому, что readln - это вызов процедуры, требующий вмешательства пользователя. Такие вмешательства лучше не размазывать по всей программе внутри процедур, а сконцентрировать в одном месте, лучше в главной программе.

Ясно..

Добавлено спустя 2 минуты 12 секунд:
Вот никак не придумаю как решать следующую задачу (посчитать разность).Уже <<весь мозг сломал>>. :?: :( :|
Аватара пользователя
Paster Fob
постоялец
 
Сообщения: 188
Зарегистрирован: 22.02.2011 21:53:36
Откуда: Новосибирск.

Re: Разбор примеров из книги

Сообщение Oleg_D » 14.09.2012 11:06:14

Так тем же порядком, как во 2-м классе.
Oleg_D
постоялец
 
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

Re: Разбор примеров из книги

Сообщение Vadim » 14.09.2012 11:17:35

Paster Fob писал(а):
tema писал(а):Дело в том, что readln в теле процедуры не есть гуд:

Почему?

Можно ввод данных пользователя поместить в отдельную процедуру, которая и будет состоять из одних сплошных ReadLn. ;)
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Разбор примеров из книги

Сообщение Paster Fob » 15.09.2012 06:56:24

Paster Fob писал(а):Вот никак не придумаю как решать следующую задачу (посчитать разность).Уже <<весь мозг сломал>>. :?: :( :|
Oleg_D писал(а):Так тем же порядком, как во 2-м классе.

Всё равно ничего не получается.При вычитании нужно из большего вычесть меньшее и при необходимости подставить или убрать -,а т.к. программа работает не с целым числом а с отдельными цифрами,то здесь и получается проблема.Нужно каким-то образом выяснить какое сверхбольшое число больше а уж потом вычислять разность.Да и с переносом не ясно как быть,здесь же надо не переносить,а наоборот занимать у старшего числа единицу.Уже пару листов A4 исписал,только конкретного ничего не получается.
Аватара пользователя
Paster Fob
постоялец
 
Сообщения: 188
Зарегистрирован: 22.02.2011 21:53:36
Откуда: Новосибирск.

Re: Разбор примеров из книги

Сообщение bormant » 15.09.2012 10:40:25

Paster Fob писал(а):Уже пару листов A4 исписал,только конкретного ничего не получается.

Намекну, с вашего позволения:
Код: Выделить всё
  _ 631  _ 345  _ 1000   или, если  1+9-4 = 6
    345    631     714   познаково:   9-1 = 8
   ----   ----   -----                9-7 = 2
    286   -714     286
Во втором столбике в результате "минус" условный.
См. "дополнительный код" как представление числа.
Аватара пользователя
bormant
постоялец
 
Сообщения: 407
Зарегистрирован: 21.03.2012 11:26:01

Re: Разбор примеров из книги

Сообщение Oleg_D » 18.09.2012 11:22:03

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 раз.
Причина: опечатка
Oleg_D
постоялец
 
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

Re: Разбор примеров из книги

Сообщение Paster Fob » 27.09.2012 21:22:37

Во-первых я пытался решить через массивы.
Во-вторых используя строки я просто сравнивал 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;
  ......

В-третьих я не мог придумать как высчитать из меньшего большее и как занимать единицу у впереди стоящей цифры.
В-четвёртых корплю над "Наказанием". :shock: :wink:
Аватара пользователя
Paster Fob
постоялец
 
Сообщения: 188
Зарегистрирован: 22.02.2011 21:53:36
Откуда: Новосибирск.

Re: Разбор примеров из книги

Сообщение Oleg_D » 27.09.2012 23:16:48

Paster Fob писал(а):В-четвёртых корплю над "Наказанием".

Тут я предлагаю взять за основу уже готовые процедуры на основе строк и поколдовать немного со знаками. В конце концов, всё сводится к тем же сложению и вычитанию.
Oleg_D
постоялец
 
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

Re: Разбор примеров из книги

Сообщение Paster Fob » 30.09.2012 10:56:49

Не могу понять почему так происходит,в чём проблема?
Код: Выделить всё
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.


Изображение
Аватара пользователя
Paster Fob
постоялец
 
Сообщения: 188
Зарегистрирован: 22.02.2011 21:53:36
Откуда: Новосибирск.

Re: Разбор примеров из книги

Сообщение Oleg_D » 30.09.2012 12:08:18

Paster Fob писал(а):Не могу понять почему так происходит,в чём проблема?

Элементарно, Ватсон. Строки сравниваются символ за символом слева направо. Если очередной символ окажется "больше" другого, то и вся строка с этим символом считается "большей". Независимо от её длины и последующих символов. См. сравнение строк в моём варианте программ.
"45" > "1000" потому, что "4" > "1"
Oleg_D
постоялец
 
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

Re: Разбор примеров из книги

Сообщение Paster Fob » 30.09.2012 12:58:25

Ясно,я ориентировался на главу 44 где сказано про сравнение строк.В таком случае нужно добавить в книгу,ещё один пример сравнения:
Код: Выделить всё
Writeln ('ABC' > 'BC')    {false}

И объяснить почему так.
Аватара пользователя
Paster Fob
постоялец
 
Сообщения: 188
Зарегистрирован: 22.02.2011 21:53:36
Откуда: Новосибирск.

Пред.След.

Вернуться в Книга "Песни о Паскале"

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

Рейтинг@Mail.ru