Форум «Всё о Паскале» _ Задачи _ Исправить исхондник
Автор: *alt 24.05.2007 1:58
Задача Пусть дан текст (т.е. мы его вводим сами), заканчивающийся точкой. Текст состоит из слов, разделённых пробелами. Слово - последовательность латинских букв. Напечатайте слова текста, имеющие нечетный номер, в которых нет ни одной повторяющейся буквы.
Вот решение задачи, но в процедуре find есть ошибка (т.е она работает неправильно).
Код
const n_max=1000; {макс длина текста} eot='.'; type litters = set of 'a'..'z'; {тип множества лат букв} var txt:array [1..n_max] of char; {текст} n:integer;
{процедура ввода текста} procedure read_text; var i:integer; begin Writeln ('Введите текст: '); i:=0; repeat repeat //два репида, эт чтоб вводить построчно i:=i+1; read(txt[i]); until eoln or (i=n_max) or (txt[i]=eot); readln; until (i=n_max) or (txt[i]=eot); if txt[i]=eot then n:=i-1 else n:=i; end;
{процедура поиска нужных слов} procedure find; var j,i:integer; s:string; m:litters; f:boolean; begin i:=1; j:=1; repeat s:=''; m:=[]; f:=false; repeat f:=txt[j] in m; m:=m+[txt[j]]; s:=s+txt[j]; j:=j+1; until (txt[j]=' ') or f or (txt[j]='.'); if not f and odd(i) then write(s); i:=i+1; until txt[i]='.';
end; begin {main} read_text; find; readln; end.
Из цикла не правильно выходит (он конеш работает, но только, когда во всех словах буквы не повторяются). Переделайте пожалуйста...
Автор: nikita182 24.05.2007 2:48
Цитата(*alt @ 23.05.2007 22:58)
Код
if not f and odd(i) then write(s);
я так полагаю, этот кусок печатает слово, если оно прошло проверку! но согласно твоему тексту прораммы переменная f не может принимать значения тру, т.е. проверка только на четность у тебя.
Автор: volvo 24.05.2007 3:22
Цитата
согласно твоему тексту прораммы переменная f не может принимать значения тру
Это почему еще?
А здесь:
Цитата
f:=txt[j] in m;
?
Автор: nikita182 24.05.2007 3:45
да точно.
сказывается поражение ливерпуля((
Автор: nikita182 24.05.2007 4:16
ввел: 'nikita'
как просматривает до второй 'i' (т.е. s = 'niki'), строка s сбрасывается, счетчик слов i плюсуется, а просмотр продолжается-то у тебя с буквы 't', а не со следующего слова...
procedure find; var j,i:integer; s:string; m:litters; f:boolean; begin i:=1; j:=1; repeat s:=''; m:=[]; f:=false; repeat f:=f or (txt[j] in m); m:=m+[txt[j]]; s:=s+txt[j]; j:=j+1; until (txt[j]=' ') or (txt[j]='.'); if not f and odd(i) then write(s); i:=j; until txt[i]='.';
end;
Автор: nikita182 24.05.2007 4:42
Цитата(volvo @ 24.05.2007 1:37)
f:=f or (txt[j] in m);
мне не раз встречаются строки такого типа, никак не пойму чтоже тут делается.. поясни, пожалуйста.
Автор: Ozzя 24.05.2007 10:29
Цитата(nikita182 @ 24.05.2007 1:42)
мне не раз встречаются строки такого типа, никак не пойму чтоже тут делается.. поясни, пожалуйста.
f - переменая логического типа txt[j] in m - входит ли элемент массива во множество m итого^ f или входит ли элемент массива во множество m
Автор: volvo 24.05.2007 13:43
Цитата
никак не пойму чтоже тут делается..
Тут накапливается результат. То есть, поскольку изначально f:=false, то если не будет ни одного j, для которого выполнится условие (text[j] in m), значение f так и останется false (поскольку false OR false = false)... Но как только хоть однажды условие выполнится, сработает false OR true = true, значение f переключится в "истину", и останется таковым пока не будет опять сброшено в начале следующей итерации.
Автор: nikita182 24.05.2007 14:21
вроде понял, но в чем отличие от
f:=txt[j] in m;
ведь в данном случае у нас также f будет false пока не выполнится условие (text[j] in m)? или я путаю что-то?
Автор: volvo 24.05.2007 14:27
Нет... В случае f:=txt[j] in m; у тебя в F запишется результат последней проверки на вхождение элемента во множество (у меня же - сохраняется результат накопленный, после просмотра всего слова)... И если (как, собственно, и было) добавить условием выхода (not F) в Until, то выполнение внутреннего цикла, конечно, прекратится, однако следующая итерация-то начнется не там где этого ждешь, а прямо со следующей буквы... Ты это видел, когда вводил "nikita".
Автор: nikita182 24.05.2007 14:31
вот теперь понял, спасибо.
Автор: *alt 24.05.2007 15:44
Цитата(volvo @ 24.05.2007 1:37)
*alt, вот так попробуй:
procedure find; var j,i:integer; s:string; m:litters; f:boolean; begin i:=1; j:=1; repeat s:=''; m:=[]; f:=false; repeat f:=f or (txt[j] in m); m:=m+[txt[j]]; s:=s+txt[j]; j:=j+1; until (txt[j]=' ') or (txt[j]='.'); if not f and odd(i) then write(s); i:=j; until txt[i]='.';
end;
Неа, чёт не работает, типо того, что было. если введу funky soull kill job, то выводит funky job.
Автор: volvo 24.05.2007 16:02
Да, немного пришлось поменять:
procedure find; var j,i:integer; s:string; m:litters; f:boolean; begin i:=1; j:=1; repeat s:=''; m:=[]; f:=false; repeat f:=f or (txt[j] in m); m:=m+[txt[j]]; s:=s+txt[j]; j:=j+1; until (txt[j]=' ') or (txt[j]='.'); if not f and odd(i) then write(s); i:=i + 1; { <--- Здесь - вернул как было } until txt[j]='.'; { <--- Здесь - изменение }
end;
Автор: *alt 24.05.2007 16:10
Спасибо, volvo. Кажется работает нормально. И ещё, не совсем по теме, что значит запись const limits = [#0..#32,'.']; а именно #0..#32
Автор: Ozzя 24.05.2007 16:25
Цитата(*alt @ 24.05.2007 13:10)
Спасибо, volvo. Кажется работает нормально. И ещё, не совсем по теме, что значит запись const limits = [#0..#32,'.']; а именно #0..#32
константа перечисляемого типа, включающая в себя коды символов от 0 до 32 - служебные.