Страница 1 из 2
Глава 23. Задание " Б ".
Добавлено: 29.10.2016 00:12:13
Герман
Задание:
Б) Напишите функцию для определения позиции буквы в заданной строке. Функция должна вернуть позицию первой такой буквы или ноль, если буквы в строке нет. Напишите программу для проверки функции.
В книге с ответами есть ответ на задание " В ".
Вот мои потуги:
Код: Выделить всё
{--- 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.
И все же. Почему мой код не работает?
Re: Глава 23. Задание " Б ".
Добавлено: 29.10.2016 06:35:24
Zhbr
Счётчик в твоем цикле util не на работает, то есть его вообще нет) i постоянно равна 1, цикл бесконечный получается.
Re: Глава 23. Задание " Б ".
Добавлено: 29.10.2016 09:13:18
Лекс Айрин
и, кстати, в repeat... until неправильное условие -- если уж делать этим циклом, то надо проверить размер строки и в условии проверять равно ли ей i.
так как бы не совсем правильно
достаточно
кстати, в работающем коде тоже есть небольшая ошибка
лучше поменять на
дело в том, что вычисление длинны строки в каждой итерации цикла слишком затратно.
Re: Глава 23. Задание " Б ".
Добавлено: 29.10.2016 11:37:47
bormant
Лекс Айрин писал(а):дело в том, что вычисление длинны строки в каждой итерации цикла слишком затратно.
Вероятно, чтение документации, в которой прямо сказано, что начальное и конечное значения вычисляются один раз до начала цикла и до инициализации счетчика цикла, еще затратнее...
http://www.freepascal.org/docs-html/ref/refsu59.html
Re: Глава 23. Задание " Б ".
Добавлено: 29.10.2016 11:43:53
Герман
Спб за помощь. Все таки я не одолел конструкцию через repeat
until
Re: Глава 23. Задание " Б ".
Добавлено: 29.10.2016 12:18:41
bormant
Герман писал(а):Спб за помощь. Все таки я не одолел конструкцию через 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;
Re: Глава 23. Задание " Б ".
Добавлено: 30.10.2016 08:31:52
Герман
Спб. Я еще не дошел в книге до Inc(i).
Re: Глава 23. Задание " Б ".
Добавлено: 30.10.2016 09:33:05
bormant
Inc(i) тождественно i:=i+1.
Re: Глава 23. Задание " Б ".
Добавлено: 31.10.2016 09:05:09
Лекс Айрин
bormant писал(а):Лекс Айрин писал(а):дело в том, что вычисление длинны строки в каждой итерации цикла слишком затратно.
Вероятно, чтение документации, в которой прямо сказано, что начальное и конечное значения вычисляются один раз до начала цикла и до инициализации счетчика цикла, еще затратнее...
http://www.freepascal.org/docs-html/ref/refsu59.html
ок. Про этот нюанс я откровенно забыл. Но все равно не стал бы на него надеяться. Ибо это конкретная реализация, на которую программист не должен опираться.(например, длинна строки может поменяться в цикле,(в сторону уменьшения), что может привести к непредсказуемым последствиям.)
Re: Глава 23. Задание " Б ".
Добавлено: 03.11.2016 07:24:19
bormant
Лекс Айрин писал(а):Про этот нюанс я откровенно забыл. Но все равно не стал бы на него надеяться. Ибо это конкретная реализация, на которую программист не должен опираться.(например, длинна строки может поменяться в цикле,(в сторону уменьшения), что может привести к непредсказуемым последствиям.)
1) нет. Это поведение с незапамятных времён и, если правильно путаю, свойство самого языка, как и неопределенность значения счетчика цикла по завершении цикла не по Break.
2) для меняющейся длины строки, где возможно используют
for i:=Length(s) downto 1 do ...
где невозможно, там и экономия с отдельной переменной теряет смысл, остаются
while (i<=Length(s)) and ... do ...
либо опора на барьер в виде завершающего #0 для строк без предвычисленный длины.
Re: Глава 23. Задание " Б ".
Добавлено: 03.11.2016 09:28:05
Лекс Айрин
bormant писал(а):1) нет. Это поведение с незапамятных времён и, если правильно путаю, свойство самого языка, как и неопределенность значения счетчика цикла по завершении цикла не по Break.
Это неважно, так как может поменяться в любой момент. Да и не является это свойством языка -- это метод реализации через ассемблерную инструкцию Loop. А насчет неопределенности... значение счетчика неопределено вне цикла независимо от способа выхода из него. По крайней мере в классическом паскале.
bormant писал(а):2) для меняющейся длины строки, где возможно используют
for i:=Length(s) downto 1 do ...
где невозможно, там и экономия с отдельной переменной теряет смысл, остаются
while (i<=Length(s)) and ... do ...
либо опора на барьер в виде завершающего #0 для строк без предвычисленный длины.
Я бы вообще осторожно использовал здесь for
Re: Глава 23. Задание " Б ".
Добавлено: 05.11.2016 18:54:30
bormant
Это может поменяться в любой момент примерно с той же вероятностью, что и полностью выбросить синтаксис Паскаля и заменить его чем-то другим. С 1972 года не менялось, а тут ни с того ни с сего поменяется.
http://www.eah-jena.de/~kleine/history/ ... Report.pdf , стр. 29.
Re: Глава 23. Задание " Б ".
Добавлено: 07.11.2016 09:30:04
Лекс Айрин
bormant писал(а):Это может поменяться в любой момент примерно с той же вероятностью, что и полностью выбросить синтаксис Паскаля и заменить его чем-то другим.
Согласен, но... сколько лет пользовались досом и вдруг появилась винда...
Re: Глава 23. Задание " Б ".
Добавлено: 07.11.2016 10:53:22
daesher
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
Короче, изначально действует правило -
не менять начальное и конечное значение. Что будет, если оно изменится - по идее, зависит от реализации. Другое дело, что легче реализовать расчёт один раз, чем перепроверять каждый раз.
Re: Глава 23. Задание " Б ".
Добавлено: 07.11.2016 13:56:46
Лекс Айрин
Короче, изначально действует правило - не менять начальное и конечное значение. Что будет, если оно изменится - по идее, зависит от реализации. Другое дело, что легче реализовать расчёт один раз, чем перепроверять каждый раз.
А представьте, что паскаль будет переделываться на выполнение под многопоточное (например, квантовое) выполнение и все действия смогут выполняться одновременно для всего массива и в следующей итерации размер массива может измениться. (из-за вставляемых/убираемых элементов. Ладно,если размер будет просто увеличиваться (массив расходится)... а если массив сходится?
Указанное поведение заточено под массивы со статическим размером. Уже при динамических придется использовать другие методы. Или пользоваться аварийным выходом в виде оператора прерывания цикла. (фактически, запретным goto из тела цикла).