Помощь - Поиск - Пользователи - Календарь
Полная версия: множества
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Sqrin
Дана последовательность, содержащая от 2 до 50 слов, в каждом из которых от 1 до 8 строчных латинских букв; между соседними словами – запятая или не менее одного пробела, за последним словом - точка.
Напечатать те слова последовательности, которые отличны от последнего слова и
удовлетворяют следующему свойству:
- в слове гласные чередуются с согласными;
Напечатать те слова последовательности, которые отличны от последнего слова,
предварительно преобразовав каждое из них по следующему правилу:
- если слово нечетной длины, то удалить его среднюю букву.


напишите плиз
volvo
Цитата(Sqrin @ 11.05.05 0:05)
напишите плиз

Помочь - пожалуйста, но писАть полностью :no:
Хоть что-нибудь уже начато?

Для начала можно прочитать здесь: FAQ: Множества, чтобы иметь представление о том, с чем придется иметь дело...
asCOOLs
ето понятно ... вот тока определение согласные или не согласные ?
сделать отдельный блок данных с забитыми гласными и проверять? что не соглас то гласные ? или как лучше оформиь?
volvo
const
glas = ['a', 'e', 'i']; { и так далее }
soglas = ['a' .. 'z'] - glas;
Sqrin
как задатьмножество я понимаю
а вот....
Напечатать те слова последовательности, которые отличны от последнего слова и
удовлетворяют следующему свойству:
- в слове гласные чередуются с согласными;
Напечатать те слова последовательности, которые отличны от последнего слова,
предварительно преобразовав каждое из них по следующему правилу:
- если слово нечетной длины, то удалить его среднюю букву
сам алгоритм првореки не могу накатать
volvo
Цитата(Sqrin @ 15.06.05 9:19)
Напечатать те слова последовательности, которые отличны от последнего слова

Ну, для этого допустим надо разбивать строку на слова, это тоже уже было: FAQ: Строки
А потом вот так:
Count := GetWords(s, arr, []);
for i := 1 to pred(Count) do
If (arr[i] <> arr[Count]) and ({ здесь проверяй чередование })
then writeln(arr[i]);


Цитата(Sqrin @ 15.06.05 9:19)
если слово нечетной длины, то удалить его среднюю букву
Элементарно:
If odd(length(s)) then delete(s, succ(length(s) div 2), 1);
Sqrin
о елки .. оболдеть... что то я запутолся...
ксати насчет katrin это девушка из соседнией группы....

Program GlasSogas_lol;
Uses crt;
Const
n = 50;
Sogl : set of char = [,'Ь','Ъ','б','в','г', 'д','ж','з','й','к','л','м','н','п','р','с','т','ф',
'х','ц','ч','ш','щ','ь','ъ'];
Glas : set of char = ['а','е','и','о', 'у','ы','э','ю','я'];
Var
S, S_Glas, S_Sogl : string[n];
I : integer;
Begin
ClrScr;
Write('Введите строку (50 символов): ');

Readln(Stroka);
ето вроде начало... как терь сюда прикрипить
разбиение строки по словам?
Archon
1. не 50 символов в строке, а 50 слов. Поставь просто string.
2. создай wrds : array [1..50] of string[8];
3. загоняй слова в массив. Перебирай все символы(при этом wrds[j]:=wrds[j]+Stroka[i], i - счётчик цикла, j - счётчик слов), если символ не в множестве гласных и не в множестве согласных, значит разделитель(j++ :D ).

добавлено:
Начало должно выглядеть так
Код

Uses crt;
Const
 Glas = ['A','E','I','O','U','Y'];
 Sogl = ['A'..'Z'] - Glas;
Var
 S : string;
 words : array [1..50] of string[8];
 I,j : integer;
 old : char;
Begin
 ClrScr;
 Write('Введите строку : ');
 Readln(S);
 old := ' ';   {Тута пробел}
 j := 1;       {Первое слово}
 For i := 1 to length(S) do  {Сканируем строку}
 Begin
   if UpCase(S[i]) in Sogl + Glas then words[j] := words[j] + S[i]{если буква, добавляем к текущему слову}
   else if UpCase(old) in Sogl + Glas then Inc(j);{Если не буква, а предыдущий символ - буква, увеличиваем номер слова}
   old := S[i];  {Сохраняем символ, на следующем шаге он станет предыдущим}
 End;
Malice
Если я все правильно понял, то 50 слов * (8 символов +1 разделитель) = 450 символов максимум. Стрингом никак smile.gif
klem4
Цитата(Malice @ 16.06.05 14:03)
Если я все правильно понял, то 50 слов * (8 символов +1 разделитель) = 450 символов максимум.  Стрингом никак  smile.gif


что значит ? программа, описаная выше, видишь ? там объявлен массив строк по 8 символов

так что никаких проблем.
Malice
Цитата(klem4 @ 16.06.05 14:07)
что значит ? программа, описаная выше, видишь ? там объявлен массив строк по 8 символов

так что никаких проблем.


Массив заполняется при вводе ? Нет. Там readln (s).
Archon
:D :D :D :D :D :D :D
Можно
S : string;
заменить на
S : array [1..450] of char;
только вводить сложнее.

И вообще, нефиг придираться, там ещё написано:
Цитата
между соседними словами – запятая или не менее одного пробела

Если пробелов ставить можно сколько угодно, нам придётся безразмерную строку делать что-ли? <_<
Malice
Цитата(Archon @ 16.06.05 14:23)
Если пробелов ставить можно сколько угодно, нам придётся безразмерную строку делать что-ли? <_<


Зря ты так. Может в этом и суть smile.gif Описано уж больно все конкретно.
Придется заполнять массив при вводе, используя что-то типа RLe компресии smile.gif и array [1..499] Ж)
volvo
Цитата(Malice @ 16.06.05 14:38)
Может в этом и суть smile.gif Описано уж больно все конкретно.

Что именно КОНКРЕТНО описано? Я например виже только то, что есть ограничение на длину слова... С остальным никаких проблем нет, но если тебе так хочется поумничать, то просто напиши свою функцию ввода строки посимвольно... 10 минут работы вместе с отладкой...

В чем проблемы?
klem4
Можно вводить сразу массив слов :

uses crt;
const limits=[' ',',','.'];
var
s:string;
ch:char;
posl:array[1..50] of string[8];
i,j,n:integer;

Begin
clrscr;

write('n='); readln(n);

j:=0;
repeat
s:='';
i:=0;
repeat
inc(i);
ch:=readkey;
write(ch);
if not (ch in limits) then
s:=s+ch;
until (ch in limits)or(i=8);
inc(j);
posl[j]:=s;
until j=n;

readln;
end.



немного лагает, надо поправить
Archon
Да ну вас... Мы же с Malice пошутили... :p2:

У нас для этого есть раздел "ЮМОР"...
А сюда люди когда приходят, им не до шуток... angry.gif


Да, сэр, так точно, сэр! mellow.gif
klem4
Не уверен что отрабатывает полностью правильно, так что не бейте , здесь вариант с фиксированным числом записей, взгляните :

uses crt;
const
limits=[' ',',','.'];
glasn=['q','e','y','u','i','o','a'];
sogl=['a'..'z']-glasn;
var
s,ss:string;
ch:char;
posl:array[1..50] of string[8];
i,j,k,n:integer;
flag:boolean;

Begin
clrscr;

write('n='); readln(n);

j:=0;
repeat
s:='';
i:=0;
repeat
inc(i);
ch:=readkey;
write(ch);
if not (ch in limits) then
s:=s+ch;
until (ch in limits)or(i=8);
inc(j);
posl[j]:=s;
until j=n;

writeln;

for i:=1 to n do
if (posl[i]<>posl[n])or(n=1) then begin
ss:=posl[i];
if odd(length(ss)) then
delete(ss,length(ss) div 2 + 1,1);

flag:=true;

k:=1;

case ss[k] in glasn of
True : begin

while(k<=length(ss))and(flag) do
if not((ss[k] in glasn)and(ss[k+1] in sogl)) then
flag:=false
else inc(k,2);

if flag then
writeln('YES : ',posl[i]);
end;

False : begin
while(k<=length(ss))and(flag) do
if not((ss[k] in sogl)and(ss[k+1] in glasn)) then
flag:=false
else inc(k,2);

if flag then
writeln('YES : ',posl[i]);
end;
end;
end;

readln;
end.



если надо, можно сделать такойже ввод, только без фиксированного числа последовательностей
Guest
Цитата(volvo @ 16.06.05 14:55)
Что именно КОНКРЕТНО описано? Я например виже только то, что есть ограничение на длину слова... С остальным никаких проблем нет, но если тебе так хочется поумничать, то просто напиши свою функцию ввода строки посимвольно... 10 минут работы вместе с отладкой...

В чем проблемы?


Нежнее, volvo, нежнее. Работа программиста приучает к буквоедству, если в задании возможны разночтения - я всегда уточняю. Эти цифры просто режут глаз. Почему именно 50, а на пример не 10 ? Сложнее программа от этого не становится, а за 255 выталкивает. И окончание ввода конкретным символом тоже подводит к посимвольному вводу (это к until ch='.'). И ни каких проблем в этом нет. Говорю-что думаю. Ни каких шуток - все серьезно.
volvo
Цитата(klem4 @ 16.06.05 16:35)
Не уверен что отрабатывает полностью правильно

Вот этот кусок вызывает сомнения:
   clrscr;

write('n='); readln(n);

j:=0;
repeat
s:='';
i:=0;
repeat
inc(i);
ch:=readkey;
write(ch);
if not (ch in limits) then
s:=s+ch;
until (ch in limits)or(i=8);
inc(j);
posl[j]:=s;
until j=n;

writeln;
{ Добавлено мной }
for i := 1 to n do writeln(posl[i]);

Вот что я вводил:
n=3
start<пробел>finish<пробел><пробел>

... на этом ввод прерывается и мне распечатывает:
Цитата
start
finish
<пустая строка или пробел>


А у меня получилось вот такое (для ввода слов):
uses crt;

const
maxlen = 8;
maxwords = 10;
var
words: array[1 .. maxwords] of
string[maxlen];

function get_words: integer;
const
_delimit = [' ', ','];
_endstr = ['.'];
var
ch: char;
word_count: integer;
begin
word_count := 1;
repeat
ch := readkey;
if not (ch in (_delimit+_endstr)) then begin
if length(words[word_count]) < maxlen then begin
words[word_count] := words[word_count] + ch; write(ch)
end;
end
else
if ch in _delimit then begin
write(ch);
while ch in _delimit do ch := readkey;

if not (ch in _endstr) then begin
inc(word_count); words[word_count] := ch; write(ch);
end;
end;
until ch in _endstr;
writeln;
get_words := word_count;
end;

var
i: integer;
begin
for i := 1 to get_words do
writeln(words[i])

{ и пошла обработка }
end.
klem4
А если так :

write('n='); readln(n);

j:=0;

repeat
s:='';
i:=0;

flag:=false;
repeat
inc(i);
ch:=readkey;
write(ch);
if not (ch in limits) then begin
flag:=true;
s:=s+ch;
end;

until (ch in limits)or(i=8);

if flag then begin
inc(j);
posl[j]:=s;
end;
until j=n;
volvo
klem4, а как тебе вот такой способ решения первого задания (насчет чередования)?
const
glasn=['q','e','y','u','i','o','a'];
sogl=['a'..'z']-glasn;

type char_set = set of char;
const
arrset: array[boolean] of char_set =
(glasn, sogl);
var
flag, which:boolean;
...
for i := 1 to n-1 do begin
which := posl[i][1] in glasn;
flag := true; j := 1;
while (j <= length(posl[i])) and flag do begin
flag := posl[i][j] in arrSet[which xor odd(j)];
inc(j)
end;

if flag and (posl[i] <> posl[n])
then writeln(posl[i])
end;

;)
klem4
Цитата(volvo @ 17.06.05 13:58)
klem4, а как тебе вот такой способ решения первого задания (насчет чередования)?



...красиво :D
Archon
volvo, я твою функцию get_words чуток подправил и сделал более дотошной:
uses crt;

const
maxlen = 8;
minwords = 2;
maxwords = 50;
var
words: array[1 .. maxwords] of
string[maxlen];

function get_words: integer;
const
_alphabet = ['a' .. 'z'];
_delimit = [' ', ','];
_endstr = ['.'];
var
ch: char;
word_count: integer;
begin
word_count := 1;
repeat
ch := readkey;
if (ch in _alphabet) then begin
if length(words[word_count]) < maxlen then begin
words[word_count] := words[word_count] + ch; write(ch)
end
end
else
if (ch in _delimit) and (words[word_count] <> '') then begin
if (word_count < maxwords) then begin
inc(word_count); write(ch)
end
end
until (ch in _endstr) and (word_count >= minwords);
write(ch);
writeln;
get_words := word_count;
end;

var
i: integer;
begin
ClrScr;
for i := 1 to get_words do
writeln(words[ i ]);

{ и пошла обработка }
end.


В старом варианте:
1. Можно было ввести меньше 2-х слов;
2. Если первым символом ввести разделитель, то возникало пустое слово, что противоречит условию;
3. Можно было ввести больше maxwords слов что приводило к некорректной обработке массива;
4. По условию все слова должны состоять из строчных латинских букв, а можно было набирать из любых символов кроме разделителей и точки.

Ну а теперь такого нет B)
Archon
volvo, оценил проверку на чередование.
Не знал, что можно задавать массив так:
Цитата
arrset: array[boolean]
Также, как и не знал, что q - гласная буква, хех.

Осталось только скомпоновать:
program da_zdravstvuet_kollektivniy_trud_ura;
uses crt;

const
maxlen = 8;
minwords = 2;
maxwords = 50;
_glasn = ['q','e','y','u','i','o','a'];
_sogl = ['a'..'z'] - _glasn;

var
words : array[1 .. maxwords] of
string[maxlen];

function get_words: integer;
const
_alphabet = _glasn + _sogl;
_delimit = [' ', ','];
_endstr = ['.'];
var
ch: char;
word_count: integer;
begin
word_count := 1;
repeat
ch := readkey;
if (ch in _alphabet) then begin
if length(words[word_count]) < maxlen then begin
words[word_count] := words[word_count] + ch; write(ch)
end
end
else
if (ch in _delimit) and (words[word_count] <> '') then begin
if (word_count < maxwords) then begin
inc(word_count); write(ch)
end
end
until (ch in _endstr) and (word_count >= minwords);
write(ch);
writeln;
get_words := word_count
end;

type
char_set = set of char;

const
arrset: array[boolean] of char_set = (_glasn, _sogl);

var
flag, which : boolean;
i, j, n : integer;

begin
clrscr;
writeln('Введите строку (слов: 2-50; букв в слове: 1-8;');
writeln(' между словами '' '' или '',''; в конце ''.''):');
n := get_words;
writeln('Выборка по условию 1:');
for i := 1 to n - 1 do begin
if words[i] <> words[n] then begin
which := words[i][1] in _glasn;
flag := true; j := 1;
while (j <= length(words[i])) and flag do begin
flag := words[i][j] in arrSet[which xor odd(j)];
inc(j)
end;
if flag then write(' ',words[i])
end
end;

writeln;
writeln('Выборка по условию 2:');
for i := 1 to n - 1 do begin
if odd(length(words[i])) and (words[i] <> words[n]) then begin
delete(words[i], length(words[i]) div 2 + 1, 1);
write(' ',words[i]);
end
end;

readkey
end.


Забавно будет, если Sqrin попросил задачку для школы <_<
Malice
Цитата(klem4 @ 17.06.05 14:03)
...красиво  :D


Раз такая пьянка пошла, чередование так проще проверить:


st:='';
for k:=1 to length(words[i]) do
st:=st+char($30+byte(words[i][k] in glasn));
if not((pos('00',st)>0) or (pos('11',st)>0)) then { чередуются }


и как то нагляднее :p2:

Ну, насчет наглядности, допустим, это как кому нравится... Можно еще не один вариант привести, который будет делать то же самое...
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.