Глава 23. Задание " Б ".

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

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

Глава 23. Задание " Б ".

Сообщение Герман » 29.10.2016 00:55:57

Задание:
Б) Напишите функцию для определения позиции буквы в заданной строке. Функция должна вернуть позицию первой такой буквы или ноль, если буквы в строке нет. Напишите программу для проверки функции.

В книге с ответами есть ответ на задание " В ".

Вот мои потуги:
Код: Выделить всё
{--- funkcya ---}
function Poisk(const str : string;
                      ch : char) : integer;
var i, N : integer;

begin
  Poisk := 0;
  i := 1;
  repeat
    if str[i]= ch
      then Poisk := 0 + i;
  until Poisk > 0;
end;

{--- glavnaya programma ---}

var S : string;

begin
  Write(' Vvedite stroku, '); Readln(S);
  Writeln(Poisk(S, 'A'));
  Readln;
end.

В чем моя ошибка? Help, please.

Добавлено спустя 16 минут 16 секунд:
Нашел ответ в другой теме:

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


Сбило меня с толку что команда break работает вместе с until.
И все же. Почему мой код не работает?
Герман
новенький
 
Сообщения: 26
Зарегистрирован: 27.10.2016 11:11:41

Re: Глава 23. Задание " Б ".

Сообщение Zhbr » 29.10.2016 07:35:24

Счётчик в твоем цикле util не на работает, то есть его вообще нет) i постоянно равна 1, цикл бесконечный получается.
Zhbr
новенький
 
Сообщения: 44
Зарегистрирован: 31.01.2014 02:34:21

Re: Глава 23. Задание " Б ".

Сообщение Лекс Айрин » 29.10.2016 10:13:18

и, кстати, в repeat... until неправильное условие -- если уж делать этим циклом, то надо проверить размер строки и в условии проверять равно ли ей i.

так как бы не совсем правильно
Код: Выделить всё
then Poisk := 0 + i;


достаточно
Код: Выделить всё
then Poisk := i;


кстати, в работающем коде тоже есть небольшая ошибка
Код: Выделить всё
for i:=1 to length(str) do

лучше поменять на
Код: Выделить всё
N:=  length(str);
for i:=1 to N do

дело в том, что вычисление длинны строки в каждой итерации цикла слишком затратно.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Глава 23. Задание " Б ".

Сообщение bormant » 29.10.2016 12:37:47

Лекс Айрин писал(а):дело в том, что вычисление длинны строки в каждой итерации цикла слишком затратно.

Вероятно, чтение документации, в которой прямо сказано, что начальное и конечное значения вычисляются один раз до начала цикла и до инициализации счетчика цикла, еще затратнее...
http://www.freepascal.org/docs-html/ref/refsu59.html
Аватара пользователя
bormant
постоялец
 
Сообщения: 407
Зарегистрирован: 21.03.2012 11:26:01

Re: Глава 23. Задание " Б ".

Сообщение Герман » 29.10.2016 12:43:53

Спб за помощь. Все таки я не одолел конструкцию через repeat
until
Герман
новенький
 
Сообщения: 26
Зарегистрирован: 27.10.2016 11:11:41

Re: Глава 23. Задание " Б ".

Сообщение bormant » 29.10.2016 13:18:41

Герман писал(а):Спб за помощь. Все таки я не одолел конструкцию через repeat until

Код: Выделить всё
function Poisk(const s: String; c: Char): Integer;
var i, n: Integer;
begin
  n:=Length(s); i:=0;
  repeat Inc(i) until (i>n) or (s[i]=c);
  if i>n then i:=0;
  Poisk:=i;
end;
или
Код: Выделить всё
function Poisk(const s: String; c: Char): Integer;
var i, n: Integer;
begin
  n:=Length(s); i:=0;
  repeat Inc(i) until (i>n) or (s[i]=c);
  Poisk:=i*Ord(i<=n);
end;
Аватара пользователя
bormant
постоялец
 
Сообщения: 407
Зарегистрирован: 21.03.2012 11:26:01

Re: Глава 23. Задание " Б ".

Сообщение Герман » 30.10.2016 09:31:52

Спб. Я еще не дошел в книге до Inc(i).
Герман
новенький
 
Сообщения: 26
Зарегистрирован: 27.10.2016 11:11:41

Re: Глава 23. Задание " Б ".

Сообщение bormant » 30.10.2016 10:33:05

Inc(i) тождественно i:=i+1.
Аватара пользователя
bormant
постоялец
 
Сообщения: 407
Зарегистрирован: 21.03.2012 11:26:01

Re: Глава 23. Задание " Б ".

Сообщение Лекс Айрин » 31.10.2016 10:05:09

bormant писал(а):
Лекс Айрин писал(а):дело в том, что вычисление длинны строки в каждой итерации цикла слишком затратно.

Вероятно, чтение документации, в которой прямо сказано, что начальное и конечное значения вычисляются один раз до начала цикла и до инициализации счетчика цикла, еще затратнее...
http://www.freepascal.org/docs-html/ref/refsu59.html

ок. Про этот нюанс я откровенно забыл. Но все равно не стал бы на него надеяться. Ибо это конкретная реализация, на которую программист не должен опираться.(например, длинна строки может поменяться в цикле,(в сторону уменьшения), что может привести к непредсказуемым последствиям.)
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Глава 23. Задание " Б ".

Сообщение bormant » 03.11.2016 08:24:19

Лекс Айрин писал(а):Про этот нюанс я откровенно забыл. Но все равно не стал бы на него надеяться. Ибо это конкретная реализация, на которую программист не должен опираться.(например, длинна строки может поменяться в цикле,(в сторону уменьшения), что может привести к непредсказуемым последствиям.)

1) нет. Это поведение с незапамятных времён и, если правильно путаю, свойство самого языка, как и неопределенность значения счетчика цикла по завершении цикла не по Break.
2) для меняющейся длины строки, где возможно используют
for i:=Length(s) downto 1 do ...
где невозможно, там и экономия с отдельной переменной теряет смысл, остаются
while (i<=Length(s)) and ... do ...
либо опора на барьер в виде завершающего #0 для строк без предвычисленный длины.
Аватара пользователя
bormant
постоялец
 
Сообщения: 407
Зарегистрирован: 21.03.2012 11:26:01

Re: Глава 23. Задание " Б ".

Сообщение Лекс Айрин » 03.11.2016 10:28:05

bormant писал(а):1) нет. Это поведение с незапамятных времён и, если правильно путаю, свойство самого языка, как и неопределенность значения счетчика цикла по завершении цикла не по Break.

Это неважно, так как может поменяться в любой момент. Да и не является это свойством языка -- это метод реализации через ассемблерную инструкцию Loop. А насчет неопределенности... значение счетчика неопределено вне цикла независимо от способа выхода из него. По крайней мере в классическом паскале.
bormant писал(а):2) для меняющейся длины строки, где возможно используют
for i:=Length(s) downto 1 do ...
где невозможно, там и экономия с отдельной переменной теряет смысл, остаются
while (i<=Length(s)) and ... do ...
либо опора на барьер в виде завершающего #0 для строк без предвычисленный длины.

Я бы вообще осторожно использовал здесь for
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Глава 23. Задание " Б ".

Сообщение bormant » 05.11.2016 19:54:30

Это может поменяться в любой момент примерно с той же вероятностью, что и полностью выбросить синтаксис Паскаля и заменить его чем-то другим. С 1972 года не менялось, а тут ни с того ни с сего поменяется.
http://www.eah-jena.de/~kleine/history/ ... Report.pdf , стр. 29.
Аватара пользователя
bormant
постоялец
 
Сообщения: 407
Зарегистрирован: 21.03.2012 11:26:01

Re: Глава 23. Задание " Б ".

Сообщение Лекс Айрин » 07.11.2016 10:30:04

bormant писал(а):Это может поменяться в любой момент примерно с той же вероятностью, что и полностью выбросить синтаксис Паскаля и заменить его чем-то другим.

Согласен, но... сколько лет пользовались досом и вдруг появилась винда...
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Глава 23. Задание " Б ".

Сообщение daesher » 07.11.2016 11:53:22

bormant писал(а):Это может поменяться в любой момент примерно с той же вероятностью, что и полностью выбросить синтаксис Паскаля и заменить его чем-то другим. С 1972 года не менялось, а тут ни с того ни с сего поменяется.
http://www.eah-jena.de/~kleine/history/ ... Report.pdf , стр. 29.

Там же чёрным по белому написано
The control variable, the initial value and the final value ... must not be altered by the repeated statement

Короче, изначально действует правило - не менять начальное и конечное значение. Что будет, если оно изменится - по идее, зависит от реализации. Другое дело, что легче реализовать расчёт один раз, чем перепроверять каждый раз.
daesher
постоялец
 
Сообщения: 221
Зарегистрирован: 09.03.2010 22:17:14

Re: Глава 23. Задание " Б ".

Сообщение Лекс Айрин » 07.11.2016 14:56:46

Короче, изначально действует правило - не менять начальное и конечное значение. Что будет, если оно изменится - по идее, зависит от реализации. Другое дело, что легче реализовать расчёт один раз, чем перепроверять каждый раз.


А представьте, что паскаль будет переделываться на выполнение под многопоточное (например, квантовое) выполнение и все действия смогут выполняться одновременно для всего массива и в следующей итерации размер массива может измениться. (из-за вставляемых/убираемых элементов. Ладно,если размер будет просто увеличиваться (массив расходится)... а если массив сходится?

Указанное поведение заточено под массивы со статическим размером. Уже при динамических придется использовать другие методы. Или пользоваться аварийным выходом в виде оператора прерывания цикла. (фактически, запретным goto из тела цикла).
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

След.

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

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

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

Рейтинг@Mail.ru