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

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

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

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

Сообщение Oleg_D » 08.11.2012 15:18:12

Paster Fob писал(а):что-то совсем хрень какая-то,в задаче совсем не то сказано

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

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

Сообщение deka47 » 12.11.2012 02:55:30

Код: Выделить всё
function NoG: string;
var n: string;
    ch: char;
begin
n:='';
read (INtext, ch);
while not eoln (INtext) and (ord(ch)>32) do begin n:=n+ch; read (INtext, ch); end;
NoG:=n;
end;


Что значит вот это чудо:
Код: Выделить всё
n:='';


Почему если это не указать, то ничеог не работет? Переменная n и так пустая, зачем мы присваеваем ей даже не пробел, а вообще пустое место какое-то?

И еще один вопрос, нужно создать функцию, чтобы она получала введенную стринговую строку от пользователя и печатала только первое слово с этой строки. Т.е. до первого пробела, как это сделать? С файлом как-то легче, чем с веденной строкой.
deka47
новенький
 
Сообщения: 33
Зарегистрирован: 07.10.2012 22:43:26

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

Сообщение Oleg_D » 12.11.2012 08:33:59

deka47 писал(а):Что значит вот это чудо: n:='';

Это чудо назначает строке пустое значение. Почему вы решили, что строка и так пуста? Даже если у вас получилась пустой, то это всего лишь случайность.
deka47 писал(а):И еще один вопрос, нужно создать функцию, чтобы она получала введенную стринговую строку от пользователя и печатала только первое слово с этой строки. Т.е. до первого пробела, как это сделать? С файлом как-то легче, чем с веденной строкой.

Делаем аналогично, только исследуем символы строки через индексацию:
Код: Выделить всё
R:='';
for i:=1 to Length(S) do begin
  if S[i]=Chr(32) then break;
  R:= R+S[i];
end;
Oleg_D
постоялец
 
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

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

Сообщение deka47 » 12.11.2012 13:42:34

Допустим, что строка не пустая, то почему она не выводит слово? Даже если бы строка имела какое-то значение, то нужное слово вывелось бы? Почему нет?
deka47
новенький
 
Сообщения: 33
Зарегистрирован: 07.10.2012 22:43:26

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

Сообщение Oleg_D » 12.11.2012 13:56:31

deka47 писал(а):Допустим, что строка не пустая, то почему она не выводит слово? Даже если бы строка имела какое-то значение, то нужное слово вывелось бы? Почему нет?

Выкладывайте сюда свой код и мы объясним, что к чему. Как говорят в таких случаях, телепаты в отпуске.
Oleg_D
постоялец
 
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

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

Сообщение Paster Fob » 12.11.2012 15:24:17

Oleg_D А у меня вопрос по последнему заданию из главы 46. Свинопас гришка придумал как сократить время обработки очереди... (текст точно не помню)
там есть такая фраза: "частично упорядоченная очередь" .
Это как?
Аватара пользователя
Paster Fob
постоялец
 
Сообщения: 188
Зарегистрирован: 22.02.2011 21:53:36
Откуда: Новосибирск.

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

Сообщение Oleg_D » 12.11.2012 15:34:15

Paster Fob писал(а):"частично упорядоченная очередь" .Это как?

Это значит, что очередь состоит из нескольких фрагментов, каждый из которых упорядочен, например для цифр:

1 3 7 9 + 4 6 8 + 2 3 4

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

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

Сообщение Paster Fob » 16.11.2012 20:53:47

Глава 47 задача под буквой ж)."Счастливые билеты".
вот как я решил её.

Код: Выделить всё
function sumnumber(arg:integer):integer;
var n,sum:byte;
begin
  sum:=0;
  repeat
    n:=arg mod 10;
    sum:=sum+n;
    arg:=arg div 10;
  until arg=0;
  sumnumber:=sum;
end;

function checknumber(arg:longint):boolean;
var n1,n2:integer;
begin
  checknumber:=false;
  n1:=arg mod 1000;
  n2:=arg div 1000;
  if sumnumber(n1)=sumnumber(n2) then
    checknumber:=true;
end;

var
   i,n1,n2:longint;

begin
  writeln('введите диапозон через пробел в пределах 100000-999999');
  readln(n1,n2);
  for i:=n1 to n2 do
    if checknumber(i) then
      write(i,' ');
  readln
end.


Меня интересует Правильно так писать,т.е вызов функции в функции? И ещё интересует как происходит такое сравнение
if sumnumber(n1)=sumnumber(n2) ,где хранится результат?
Аватара пользователя
Paster Fob
постоялец
 
Сообщения: 188
Зарегистрирован: 22.02.2011 21:53:36
Откуда: Новосибирск.

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

Сообщение Oleg_D » 16.11.2012 21:49:13

Ошибок не вижу, но можно и короче записать:

Код: Выделить всё
function checknumber(arg:longint):boolean;
begin
  checknumber:= sumnumber(arg mod 1000) = sumnumber(arg div 1000)
end;


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

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

Сообщение deka47 » 18.11.2012 02:28:15

Код: Выделить всё
function check (s: string; ch: char): boolean;
var i: integer;
    b: boolean;
    n: string;
   
begin
check:=false;

n:='';
for i:=1 to length (s) do if (s[i]=ch) then begin writeln('Position in the word - ', i); b:=true; end;

if b then
writeln ('There is a letter!') else
writeln ('There isn''t a letter!');

check:=b;
end;

var s: string;
    ch: char;
   
begin
write ('Write a word - '); readln (s);
write ('Write a letter - '); readln (ch);

check (s, ch);
end.


Вводите слово, потом букву, программа проверяет наличия буквы в слове. Выводит положительный ответ если буква есть и номер позиции.
Что я хочу? Вот, к примеру, если ввести PASCAL и поиск буквы А, то вот что выведет:
Код: Выделить всё
Position in the word - 2
Position in the word - 5
There is a letter!


Как сделать так, чтобы в случае наличия двух букв в слове вывело следующим образом:
Код: Выделить всё
Position in the word - 2, 5
There is a letter!


Добавлено спустя 59 минут 18 секунд:
Я немного провдинулся, теперь выводит через запятую, но после последней цифры ставит запятую тоже, вот вывод:
Код: Выделить всё
Write a word - PASCAL
Write a letter - A
Position in the word - 2, 5,
There is a letter!


Также ошибка в том, что если нету буквы в строке, то вывод будет следующий:
Код: Выделить всё
Write a word - PASCAL
Write a letter - M
Position in the word -
There isn't a letter!


Вот код:
Код: Выделить всё
n:='';
for i:=1 to length (s) do if (s[i]=ch) then begin k:=inttostr(i); n:=n + k + ', '; b:=true; end;
writeln('Position in the word - ', n);


Осталось разобраться с запятой после последней цифры и выводом, который выводиться когда нету буквы. Если нету буквы, то пусть и не выводится, что ли...
deka47
новенький
 
Сообщения: 33
Зарегистрирован: 07.10.2012 22:43:26

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

Сообщение Paster Fob » 18.11.2012 10:59:45

Нашёл свободное время,решил помочь.

Код: Выделить всё
function check2(var s:string;ch:char):boolean;
var i:integer;
begin
  check2:=false;
  for i:=1 to length(s) do
    if s[i]=ch then begin
      check2:=true;
      break;
    end;
end;

function check3(var s:string;ch:char):integer;
var i,k:integer;
begin
  k:=0;
  for i:=1 to length(s) do
    if ch=s[i] then
      inc(k);
  check3:=k;
end;

function check (var s: string; ch: char): boolean;
var i,k:integer;b:boolean;
    c:char;
begin
  k:=0;
  check:=false;
  b:=check2(s,ch);
  for i:=1 to length(s) do begin
    if b then begin
      write('Position in the word - ');
      b:=false;
    end;
    if (s[i]=ch) then begin
      inc(k);
      if check3(s,ch)=k then c:='.'
      else c:=',';
      write(i,c);
      check:=true;
      if c='.' then begin
        write(#10);
        break
      end;
    end;
  end;
end;

var s: string;
    ch: char;

begin
  write ('Write a word - ');
  readln (s);
  write ('Write a letter - ');
  readln (ch);
  if check (s, ch) then begin
    write(#13);
    writeln ('There is a letter!')
  end
  else
    writeln ('There is not a letter!');
  readln;
end.
Аватара пользователя
Paster Fob
постоялец
 
Сообщения: 188
Зарегистрирован: 22.02.2011 21:53:36
Откуда: Новосибирск.

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

Сообщение Oleg_D » 18.11.2012 13:41:22

deka47 писал(а):Вот код:
Код: Выделить всё
n:='';
for i:=1 to length (s) do if (s[i]=ch) then begin
    k:=inttostr(i); n:=n + k + ', '; b:=true;
end;
writeln('Position in the word - ', n);

Осталось разобраться с запятой после последней цифры и выводом, который выводиться когда нету буквы. Если нету буквы, то пусть и не выводится, что ли...

Здесь можно поправить так:
Код: Выделить всё
T:='';
for i:=1 to length (s) do if s[i]=ch then begin
   if Length(T)>0 then T:=T + ', ';
   T:=T + inttostr(i);
end;
if Length(T)>0
   then writeln('Positions in the word : ', T)
   else writeln ('There is not a letter!');

Ещё пару замечаний общего характера.
1. Строчными буквами k,n,m по традиции обозначают целочисленные переменные (индексы, счётчики и т.п.). Придерживайтесь традиций, и вас легче будут понимать.
2. Для передачи в процедуру/функцию неизменяемой строки пользуйтесь ссылкой const.

Добавлено спустя 32 минуты 46 секунд:
И ещё: если у кого-то будут вопросы по конкретным примерам, задачам, темам, то лучше открывать для каждого из них отдельный топик. Так будет проще отслеживать их на форуме.
Oleg_D
постоялец
 
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

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

Сообщение bormant » 22.11.2012 11:05:01

deka47 писал(а):Осталось разобраться с запятой после последней цифры и выводом, который выводиться когда нету буквы.

Например,
Код: Выделить всё
procedure check(const w: string; ch: char);
var
  i, found: integer;
begin
  found := 0;
  for i := 1 to length(w) do
    if w[i] = ch then begin
      if found = 0
      then write('Position(s) in the word: ', i)
      else write(', ', i);
      found := found + 1;
    end;
  if found > 0 then writeln('.');
  case found of
    0: writeln('There is NO letter.');
    1: writeln('There is letter.');
    else writeln('There are ', found, ' letters.');
  end;
end;

var
  s: string;
  c: char;
begin
  write('Enter a word: '); readln(s);
  write('Enter a char: '); readln(c);
  check(s, c);
end.
И прогоны:
Код: Выделить всё
$ ./test1
Enter a word: pascal
Enter a char: z
There is NO letter.

$ ./test1
Enter a word: pascal
Enter a char: s
Position(s) in the word: 3.
There is letter.

$ ./test1
Enter a word: pascal
Enter a char: a
Position(s) in the word: 2, 5.
There are 2 letters.
Аватара пользователя
bormant
постоялец
 
Сообщения: 407
Зарегистрирован: 21.03.2012 11:26:01

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

Сообщение deka47 » 24.11.2012 21:59:06

Такого примера в книге нету, интересуюсь лично для себя. Пользователь вводит слово. Как проверить одинаковы ли первая и последняя буква слова, вторая и предпоследняя, третья и третья сзади, 4-я и 4-я сзади и так все слово. Такие слова называются палиндромы (они читаются туда и назад одинаково), к примеру:
потоп, кок, поп, ротор. Ну или какие-то придуманные: лолол, мопом, копок. Мне такая задача попалась на олимпиаде, я не смог ее решить, дома уже неделю мучаюсь пробую разные варианты - не получается. Возможно ли ее сделать через for-to-do-end?
Были такие мысли:
for i:=1 to length(s) and for j:=length(s) downto 1 do - но это невозможно записать в паскале. Ну я не знаю как это сделать, множества я еще не выучил.
Также пробовал получать код каждого символа через ord(s[i]) потом все эти коды "прочитать" назад и если совпадет, то слово является палиндромом.
Но я не смог ничего реализовать, к сожалению, вот мой нынешний код:
Код: Выделить всё
var s: string;
    i, j, k: integer;
    b: boolean;
begin
writeln (s); readln (s);

j:=length(s);
k:=j;

for i:=1 to length(s) do if s[1] = s[k] then begin
    j:=length(s)-i;
if j=0 then break else
if s[i+1] = s[j] then b:=true else b:=false;
end;

if b
then writeln ('Слово є паліндромом.')
else writeln ('Слово не являється паліндромом.');
end.


Она то проверяет первый с последним, 2-ой с предпоследним и так все символы, НО в булеву переменную b попадает последняя проверка, как бы сделать так, чтобы "запоминались" все местоположения?
deka47
новенький
 
Сообщения: 33
Зарегистрирован: 07.10.2012 22:43:26

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

Сообщение Oleg_D » 24.11.2012 22:07:15

См. ответ на задачу 44-З (З - это буква, а не цифра).
Oleg_D
постоялец
 
Сообщения: 391
Зарегистрирован: 09.05.2011 11:28:36

Пред.След.

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

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

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

Рейтинг@Mail.ru