• Добро пожаловать на компьютерный форум Tehnari.ru. Здесь разбираемся с проблемами ПК и ноутбуков: Windows, драйверы, «железо», сборка и апгрейд, софт и безопасность. Форум работает много лет, сейчас он переехал на новый движок, но старые темы и аккаунты мы постарались сохранить максимально аккуратно.

    Форум не связан с магазинами и сервисами – мы ничего не продаём и не даём «рекламу под видом совета». Отвечают обычные участники и модераторы, которые следят за порядком и качеством подсказок.

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

    Не знаете, с чего начать? Создайте тему с описанием проблемы – подскажем и при необходимости перенесём её в подходящий раздел.
    Задать вопрос Новые сообщения Как правильно спросить
    Если пришли по старой ссылке со старого Tehnari.ru – вы на нужном месте, просто продолжайте обсуждение.

Не могу решить задачу на паскале

Severina

Вечная ученица
Регистрация
27 Июн 2011
Сообщения
29
Реакции
0
Баллы
0
Не могу решить задачу на паскале

Добрый вечер,
не могу решить задачу на паскале.
Задание:
Дан текст, состоящий из нескольких предложения на русском языке. Слова разделяются пробелами. Предложения оканчиваются точкой. Определить количество слов в тексте, которые начинаются и заканчиваются гласной буквой.

1) Использовать множества
2) Ввод/вывод из файла/в файл.
3) Для текста не короче 3-х предложений.
4) Использовать процедуру-подпрограмму.

Думаю, что можно решить вот так (словами):
Проверить первую букву, если она гласная, то ставим флажок true, если нет, то флажок false. Идем дальше до пробела/точки. Проверяем предшествующий символ по той же схеме. Затем если произведение этих двух символов true, то записываем в количество слов 1, если false, то 0 и идем дальше. Потом проверяем следующий символ от пробела/точки и т.д.

Только не знаю, как это реализовать и можно ли проще?
 
Program LR; uses crt;
const log1= true;
log2=false;
var k,v,l:integer;
s:string;
dat,res:text;
mn: set of char;
d: boolean;
Procedure obr(var k:integer; s:string;v,l:integer);
begin
assign(dat,'F:\pask\bin\dano.dat'); reset(dat);
assign(res,'F:\pask\bin\pr5.res'); rewrite(res);
While not eof(dat) do
begin
mn:=['a','e','i','u','o','y','A','E','I','U','O','Y'];
read(dat);
v:=1;
if s[v] in mn then s[v]:=;
else s[v]:=;
if eoln(dat) or( s in [' ','.']
then begin
if s[v-1] in mn then s[v-1]:=
else s[v-1]:=;
d:= s[v] and s[v-1];
if d= then k:=k+1;

end;
end;
end;


{----------Osnovnaya programma------------}
begin
obr(k,s,v,l);
close(dat);
writeln(res,' ');
writeln(res,'Kol-vo slov s poslednei glasnoi bukvoi ravno ',k);
repeat until keypressed;
close(res);
end.


вот, что я начала делать, но в процедуре дело не заладилось. т.к. не особо понимаю, как это вообще можно сделать
 
Немного изменила, т.е. ввела флаг.
Procedure obr(var k:integer; s:string;v,l:integer;fl1,fl2:boolean;d:boolean);
begin
assign(dat,'F:\pask\bin\dano.dat'); reset(dat);
assign(res,'F:\pask\bin\pr5.res'); rewrite(res);
While not eof(dat) do
begin
mn:=['a','e','i','u','o','y','A','E','I','U','O','Y'];
read(dat);
v:=1;
k:=0;
if s[v] in mn then fl1:=true
else fl1:=false;
if eoln(dat) or ( s in [' ','.'])
then begin
if s[v-1] in mn then fl2:=true
else fl2:=false;
d:= fl1 and fl2;
if d=true then k:=k+1;

end;
end;
end;

но опять ошибка в совместимости типов, не проходит компилятор. т.е. не могу посмотреть, что же сама и натворила.

p.s. Не подскажете хорошую литературу на эту тему?
 
но опять ошибка в совместимости типов, не проходит компилятор. т.е. не могу посмотреть, что же сама и натворила. p.s. Не подскажете хорошую литературу на эту тему?
Выложите, пожалуйста, полный листинг программы, так, чтобы параметры процедуры в описании и в обращении согласовались. Кстати, совсем не обязательно эти fl1, fl2 и d (равно, впрочем, как и s, v, l) загонять в шапку: их можно определить через Var в теле процедуры.
А литература, по моему убеждению, (кроме справочной) Вам уже не нужна, а нужна практика. И побольше.
 
Program LR; uses crt;
var k,v,l:integer;
s:string;
dat,res:text;
mn: set of char;
fl1,fl2, d: boolean;

Procedure obr(var k:integer; s:string;v,l:integer;fl1,fl2:boolean;d:boolean);
begin
assign(dat,'F:\pask\bin\dano.dat'); reset(dat);
assign(res,'F:\pask\bin\pr5.res'); rewrite(res);
While not eof(dat) do
begin
mn:=['a','e','i','u','o','y','A','E','I','U','O','Y'];
read(dat);
v:=1;
k:=0;
if s[v] in mn then fl1:=true
else fl1:=false;
if eoln(dat) or ( s in [' ','.'])
then begin
if s[v-1] in mn then fl2:=true
else fl2:=false;
d:= fl1 and fl2;
if d=true then k:=k+1;

end;
end;
end;


{----------Osnovnaya programma------------}
begin
obr(k,s,v,l);
close(dat);
writeln(res,' ');
writeln(res,'Kol-vo slov s poslednei glasnoi bukvoi ravno ',k);
repeat until keypressed;
close(res);
end.
 
На счет объявления..у меня большое недопонимание в данной теме, поэтому объявляю все в начале.
 
На счет объявления..у меня большое недопонимание в данной теме, поэтому объявляю все в начале.
А между тем всё тут вовсе не сложно.
В шапку следует помещать только те параметры, которые Вы передаете в процедуру из тела программы, а также возвращаете в программу. Те же, которые используются только внутри процедуры, можно определить, точно так же, как и в программе, создав раздел описания переменных:
Var
a,b,c:Real;
d,e:boolean;
и т.п.
Но помните - эти переменные существуют только в процедуре, для основной программы их нет!
 
Переменные в процедуре - их еще по другому называют локальными?
 
И на счет литературы, имела в виду , что нужна справочная, где хотя бы кратко указывают что надо и как делать
 
Ладно, не мучайтесь.
Сейчас попробую нарисовать программку.

Пожалуйста (имя и путь к файлу поправьте на свой лад):
Код:
CONST
 Lit=['А','Б','В','Г','Д','Е','Ж','З','И','Й','К','Л','М','Н','О','П',
      'Р','С','Т','У','Ф','Х','Ц','Ч','Ш','Щ','Ъ','Ы','Ь','Э','Ю','Я',
      'а','б','в','г','д','е','ж','з','и','й','к','л','м','н','о','п',
      'р','с','т','у','ф','х','ц','ч','ш','щ','ъ','ы','ь','э','ю','я'];
 Vow=['А','Е','И','О','У','Ы','Э','Ю','Я',
      'а','е','и','о','у','ы','э','ю','я'];
VAR
 f:Text;
 Ch:Char;
 fl1,fl2:Boolean;
 N:Byte;


BEGIN
 Assign(f,'D:\text.txt');
 ReSet(f);
 N:=0;
 REPEAT
  Repeat
   Read(f,Ch);
  Until Ch in Lit;
  If Ch in Vow then fl1:=true;
  Repeat
   Read(f,Ch);
   If Ch in Lit then
    begin
     If Ch in Vow then fl2:=true else fl2:=false;
    end;
  Until NOT (Ch in Lit);
  If fl1 and fl2 then Inc(N);
  fl1:=false;
 UNTIL EoF(f);
 Close(f);
 Writeln('The number of words beginning and ending with vowels is ',N);
 Readln
END.
 
Vladimir_S
Буду крайне признательна.
 
Vladimir_S
Большое спасибо!
Буду вникать в суть.
 
Vladimir_S
Большое спасибо!
Буду вникать в суть.
Между прочим, суть почти точно соответствует Вашему алгоритму (#1).
Различия:
1. Чем разделены слова - точками, пробелами, многоточиями, знаками вопроса и т.п. - несущественно: "обрываем" слово, когда следующий символ - НЕ буква. Дальше продолжаем перебор, пока символ не станет буквой или файл не кончится.
2. Если слово соответствует условию, счетчик увеличиваем на 1, в противном случае не делаем ничего, т.е. прибавка 0 не предусмотрена.
 
Действительно, так получается проще, если не брать во внимание, чем разделены слова.
Потихоньку разбираю, вот только что делается здесь:
Until NOT (Ch in Lit);
If fl1 and fl2 then Inc(N);
fl1:=false;
UNTIL EoF(f);
 
Действительно, так получается проще, если не брать во внимание, чем разделены слова.
Потихоньку разбираю, вот только что делается здесь:
Until NOT (Ch in Lit);
Это когда мы "въехали" в очередное слово, перебираем символы до тех пор, пока не встретим такого, который НЕ является буквой, то есть НЕ входит в множество Lit.
If fl1 and fl2 then Inc(N);
Если fl1 и fl2 оба истинны, то увеличиваем значение N на 1. Поскольку я не понял, что именно вызвало затруднение, поясню всё.
1. Если b - булева переменная, то условие "if b then" полностью эквивалентно "if b=true then". Просто сокращенная запись.
2. Inc(N) полностью эквивалентно N:=N+1.
Это исходное значение флажка при переходе к обработке комбинации (символы между словами)+(следующее слово). В принципе, эту строчку можно убрать, но тогда строку
If Ch in Vow then fl1:=true;
нужно заменить на
If Ch in Vow then fl1:=true else fl1:=false;
Что же тут непонятного? Глобальный цикл перебора символов будет продолжаться, пока не возникнет атрибут конца файла, т.е. булев параметр (элемент Паскаля) EoF ("End of File", конец файла) не примет значение TRUE.
 
Вот теперь все понятно, просто я не знала, про сокращенную запись. Спасибо за объяснение.
И еще вопрос:
Чтобы вывести результат в отдельный файл, надо добавить assign(res,'F:\pask\bin\pr5.res'); rewrite(res) ?
 
Вот теперь все понятно, просто я не знала, про сокращенную запись. Спасибо за объяснение.
И еще вопрос:
Чтобы вывести результат в отдельный файл, надо добавить assign(res,'F:\pask\bin\pr5.res'); rewrite(res) ?
А что надо выводить? Количество слов? Или сами слова? В принципе да, открытие файла на запись делается так. Только по окончании вывода надо не забыть команду Close(res);
А вот если надо выводить сами слова, начинающиеся и оканчивающиеся гласными, то программа существенно усложняется. Хотя и это решаемо.
 
Нет, сами слова выводить не надо, просто результат выводить в файл. Когда вставила, программа оставила файл результата пустым
 
Нет, сами слова выводить не надо, просто результат выводить в файл. Когда вставила, программа оставила файл результата пустым
А Вы ничего не забыли? В частности, заменить строку
Writeln('The number of words beginning and ending with vowels is ',N);
строкой
Writeln(res,'The number of words beginning and ending with vowels is ',N);
и только после этого вставить Close(res); ?
Между прочим, если вывод - файловый, то останов Readln перед финальным END следует убрать - он не нужен.
 
Назад
Сверху