Помогите, пожалуйста, очень прошу, хотя бы частично:
Перенос слова. Перенос русского слова с одной строки на другую с большей вероятностью выполняется правильно, если пользоваться следующими правилами:
1)две идущие подряд гласные можно разделить, если перед первой из них стоит согласная, а за второй идет хотя бы одна буква (буква й при этом рассматривается вместе с предшествующей ей гласной как единое целое);
2) две идущие подряд согласные можно разделить, если первой из них стоит гласная, а в той части слова, которая идет за второй согласной, имеется хотя бы одна гласная (буквы ь, ъ вместе с предшествующей согласной рассматриваются как единое целое);
3) если не удается применить первые два правила, то слово разбивают так, чтобы первая часть содержала более чем одну букву и оканчивалась на гласную, а вторая содержала хотя бы одну гласную.
Дан текст, состоящий из нескольких строк. Преобразовать текст таким образом, чтобы длина строк не превышала заданного значения, используя при этом перенос слов.
Как найти ближайший к концу строки пробел, если при заданном значении слово "как бы разбивается"? Как осуществить на Паскале приведенный выше перенос???
{ Hyphenation }
{ for Gold_Fish by Lapp }
const
Txt:array[1..153]of char= 'Chelovecheskaq dusha stolj zhe interesna, '+
'mnogoobrazna i maloizuchena, kak i Vselennaq, poskoljku '+
'vmeshaet i otrazhaet poslednww, qvlqetsq ee gologrammoi';
const
Lx=50;
Vowels:set of char=['a','A','e','E','i','I','o','O','q','Q','u','U','y','Y'];
Letters:set of char=['A'..'Z','a'..'z'];
var
l,p,t,t1:integer;
s:string;
c:char;
begin
t:=0; {текущая позиция}
t1:=t+Lx; {следующий разрыв}
if (Txt[t1-1] in Letters)and(Txt[t1] in Letters) then begin
p:=t1;
while Txt[p-1] in Letters do Dec(p);
l:=t1-p;
s:='';
while Txt[p] in Letters do begin
s:=s+Txt[p];
Inc(p)
end
end;
if Length(s)>0 then begin
WriteLn('Slovo "',s,'" obrybaetsq. Vlezaet ne bolee ',l,' bukv');
if l<2 then WriteLn('Perenesti neljsq')
else begin
c:=s[l+1];
repeat
if (c in Vowels)and(s[l] in Vowels) then begin
Insert('-',s,l+1);
WriteLn('Perenos: "',s,'"');
break
end;
c:=s[l];
Dec(l)
until l=0;
if l=0 then WriteLn('Perenesti neljsq')
end
end
else WriteLn('Razryv ne na slove');
ReadLn
end.
Ой, неужели кто-то мне помог!!! Спасибо Iapp огромное, преогромное!!!
Насчет пункта №1: извиняюсь, не так немножко, там буква й при этом рассматривается вместе с предшествующей ей гласной как единое целое (я полагаю, что если перед й стоит гласная, то они рассматриваются как единое целое).
А вот, про знаки препинания не знаю, так как в задаче ничего не сказано.
Задают такие задачи в Ивановском Государственном Энергетическом Университете на 1 курсе, факультета ИВТФ.
Помогите доделать, пожалуйста.
Я знаю, что Lapp, я даже сначала так написала, а потом посмотрела внимательнее на ник, ведь там же Iapp написано, вот и исправила
Ну так вот, ввожу я уже свой текст:
Program May;
const
Vowels:set of char=['a','A','e','E','i','I','o','O','q','Q','u','U','y','Y'];
Letters:set of char=['A'..'Z','a'..'z'];
var
l,p,t,tl,Lx:integer;
s:string;
c:char;
Txt:array[0..100] of char;
begin
writeLn('vvedite text');
readln(Txt);
writeLn('vvedite chislo');
readLn(Lx);
begin
t:=0; {tekuchaq pozisiq}
tl:=t+Lx; {sleduwchi razriv}
if (Txt[tl-1] in Letters)and(Txt[tl] in Letters) then
begin
p:=tl;
while Txt[p-1] in Letters do Dec(p);
l:=tl-p;
s:='';
while Txt[p] in Letters do begin
s:=s+Txt[p];
Inc(p)
end
end;
if Length(s)>0 then begin
WriteLn('Slovo ',s,' obrybaetsq. Vlezaet ne bolee ',l,' bukv');
if l<2 then Writeln('Perenesti neljsq')
else begin
c:=s[l+1];
repeat
if (c in Vowels)and(s[l] in Vowels) then begin
Insert('-',s,l+1);
WriteLn('Perenos: '',s,''');
break
end;
c:=s[l];
Dec(l)
until l=0;
if l=0 then WriteLn('Perenesti neljscq')
end
end
else WriteLn('Razryv ne na slove');
ReadLn;
end;
end.
{ Hyphenation
Version 0.2
for Gold_Fish by Lapp }
const
Lx=30;
Vowels_Win:set of char=
['А','а','Е','е','Ё','ё','И','и','О','о','У','у','Ы','ы','Э','э','Ю','ю','Я','я'];
Vowels_DOS:set of char=
['_',' ',':','_','р','с','_','Ё','_','R','"','г','>','л','_','н','_','о','_','п'];
var
fIn:file of char;
fOu:text;
fName,s:string;
c,d:char;
i,l,ws:integer;
Vow:set of char;
Gap,Start:boolean;
begin
Write(''ў_¤Ёв_ Ё┐п д c< ¤<п дRа┐ вЁаRў -Ёп: ');
ReadLn(fName);
Assign(fIn,fName);
ReSet(fIn);
Assign(fOu,'tst-ou-w.txt');
ReWrite(fOu);
repeat
l:=0;
s:='';
d:=#0;
repeat
d:=c;
Read(fIn,c);
if not (c in [#$0D,#$0A]) then s:=s+c;
Inc(l)
until (l=Lx)or((d=#$D)and(c=#$A))or(EoF(fIn));
WriteLn(fOu,s)
until EoF(fIn);
Close(fIn);
Close(fOu);
;ReadLn
end.
Спасибки, Lapp
Почти все дошло, кроме:
почему пишет что begin не хватает в:
Gold_Fish, извини, я неправильно (не в той кодировке запостил прогу, каюсь.. Впредь буду внимательнее.
> почему пишет что begin не хватает в:
...
> И в [#$0D,#$0A] выдает тоже ошибку, почему?
Вот это я не знаю.. пробовал смоделировать разными способами - не вышло. Будем надеяться, что оно пройдет в правильной кодировке, либо вернемся к этому потом еще раз.
> и что такое EoF?
Это признак конца файла (End of File). Это функция, которая возвращает false покак конец не достигнут, а потом true. В данном случае чтение из файла продолжается до обнаружения его конца.
> tst-ou-w.txt - это я так понимаю имя файла, а мне его заранее создать придется?
Заранее не надо, это выходной файл, он сам создается заново. Имя можно изменить, как тебе нравится, или вообще запрашивать юзера имя выходного файла, как запрашиваем имя входного.
> Никак у меня с русскими не получается, он не хочет почему-то
> переключаться на русский текст...
В Паскале, если это TP или BP, переключаться на русский сложно.. Если у тебя есть возможность, советую переключиться на FPC (FreePascal). Его можно скачать с сайта freepascal.org . Он совершенно бесплатный, но весит 28 мегов, поэтому на диалапе его качать замучишься.. Но в нем не только переключаться можно будет на русский, но и много другого хорошего (это как бы дальнейшее развитие ТР).
Но он тоже работает в кодировке DOS. И чтобы правильно копировать файлы, я настоятельно рекомендую тебе установить Far. Я тебя спрашивал о нем раньше, но ты деликатно промолчала. Ответь сейчас - можешь его поставить? Ты работаешь на своей машине или где-то еще? Весит он чуть больше 1 мега, взять можно на rarlab.com , при этом он тоже бесплатный. Когда ты его установишь, пойди в директорию
C:\Program Files\Far\Addons\Tables\Cyrillic\
и запусти скрипты KOI8-R.reg и Windows-1251.reg, нажми там все Ок, а потом перезапусти Фар.
Дальше объясню, когда подтвердишь установку..
> А так суть остального и предназначения я поняла
Вот и славненько..
> Ой сколько я много вопросов накатала, извиняюсь, но так вышло
Задавай сколько хочешь. Главное - чтоб поняла
Ниже помещаю текст программы в правильной кодировке. Но если ты его будешь копировать из браузера через notepad, то русского все равно не будет. Нужен Far. Ясно?
Ну, давай, успехов тебе..
{ Hyphenation
Version 0.2
for Gold_Fish by Lapp }
const
Lx=30;
Vowels_Win:set of char=
['└','р','┼','х','и','╕','╚','ш','╬','ю','╙','є','█','√','▌','¤','▐','■','▀',' '];
Vowels_DOS:set of char=
['А','а','Е','е','Ё','ё','И','и','О','о','У','у','Ы','ы','Э','э','Ю','ю','Я','я'];
var
fIn:file of char;
fOu:text;
fName,s:string;
c,d:char;
i,l,ws:integer;
Vow:set of char;
Gap,Start:boolean;
begin
Write('Введите имя файла для форматирования: ');
ReadLn(fName);
Assign(fIn,fName);
ReSet(fIn);
Assign(fOu,'tst-ou-w.txt');
ReWrite(fOu);
repeat
l:=0;
s:='';
d:=#0;
repeat
d:=c;
Read(fIn,c);
if not (c in [#$D,#$A]) then s:=s+c;
Inc(l)
until (l=Lx)or((d=#$D)and(c=#$A))or(EoF(fIn));
WriteLn(fOu,s)
until EoF(fIn);
Close(fIn);
Close(fOu);
ReadLn
end.
Из браузера я не копирую, а сама перепечатываю в Паскаль, мне так разобраться легче
Я установила новый, т к в старом Windows-1251.reg не было, надеюсь мне папа ничего не сделает )) , а что дальше?
Насчет внимательности, это да, стараюсь внимательно делать
Страничка freepascal.org не хочет открываться
Премногоуважаемый Lapp! ))
Я создала обычный вордовский файл, там написала текст, и все )) И все равно не так, что делать?
Здраствуйте, друг мой Lapp! )) (Снова Вас тревожит исполнительница желаний безумных старух)
))
Все я сделала как Вы указали,
будьте так любезны, скажите, что дальше нужно делать?
Вот вариант, читающий файл и выдающий отдельно строки (s) и слова (t), попавшие на разрыв (то есть те, которые нужно переносить). Вывод в файл я пока убрал (закомментировал) - вставим потом, а пока вывод идет на экран. Длину строки (Lx) можешь поварьировать. Разберись с этим, как следует, и попробуй продвинуться. На вопросы по программе отвечу..
{ Hyphenation
Version 0.3
- getting the last word
- reading the file
for Gold_Fish by Lapp }
const
Lx=40;
Vowels_Win:set of char=
['└','р','┼','х','и','╕','╚','ш','╬','ю','╙','є','█','√','▌','¤','▐','■','▀',' '];
Vowels_DOS:set of char=
['А','а','Е','е','Ё','ё','И','и','О','о','У','у','Ы','ы','Э','э','Ю','ю','Я','я'];
var
fIn:file of char;
fOu:text;
fName,s,t:string;
c,d:char;
i:integer;
Vow:set of char;
Gap,Start:boolean;
begin
{Write('Введите имя файла для форматирования: ');
ReadLn(fName);} fName:='d.txt';
Assign(fIn,fName);
ReSet(fIn);
{ Assign(fOu,'tst-ou-w.txt');
ReWrite(fOu);}
repeat
s:='';
d:=#0;
repeat
d:=c;
Read(fIn,c);
if not (c in [#$D,#$A]) then s:=s+c
until (Length(s)=Lx)or((d=#$D)and(c=#$A))or(EoF(fIn));
t:='';
if Length(s)=Lx then repeat
d:=c;
Read(fIn,c);
if not (c in [' ',#$D,#$A]) then t:=t+c;
until (c=' ')or((d=#$D)and(c=#$A))or(EoF(fIn));
if t<>'' then while not (s[Length(s)]=' ')or(Length(s)=0) do begin
Insert(s[Length(s)],t,1);
Delete(s,Length(s),1)
end;
WriteLn('s=',s:Lx+5,' t=',t);
{WriteLn(fOu,s)}
until EoF(fIn);
Close(fIn);
{ Close(fOu); }
;ReadLn
end.
Более или менее все понятно, а вот куда впихнуть буквы "й, ь, ъ" для них просто массив создать в начале, да?
P. S. Дальше не могу продвинуться, никак не составлю условие для переноса
Програмка прикольно работает, так интересно переносит твои, как ты выразился
Вот, есть первый ощутимый результат .
Я реализовал первое правило. Получается не так просто, чтобы объяснить в двух словах. Давай, лучше ты посмотришь и станешь задавать вопросы - по сделанному, а не "как дальше".. Я немного подозреваю, что ты смотришь на сделанное, как на пройденный этап, к которому нет смысла возвроащаться.. А это неправильно, так как именно в этом и состоит твой прогресс. Если можешь, развей мои подозрения .
В принципе, реализация остальных правил может быть проведена по образу и подобию первого. Так что если ты действительно разберешься, ты сможешь это сделать. Извини за отстутствие комментариев, могу добавить позже..
> Более или менее все понятно, а вот куда впихнуть буквы "й, ь, ъ"
> для них просто массив создать в начале, да?
Я вообще несколько переделал организацию ввода алфавита. Ну, увидишь, как. Это для простоты, компактности и лучшей читаемости (да и писаемости тоже ) кода, особенно когда несколько кодировок.
> P. S. Дальше не могу продвинуться, никак не составлю условие для переноса
Вот, я его составил . Enjoy!
Последние замечания:
- вывод пока идет только на экран;
- длина строки задается Lx, поварьируй ее..
Ну пока и все.
{ Hyphenation
Version 0.4
- rule #1
- getting the last w in a line
- reading the file
for Gold_Fish by Lapp }
const
Lx=37;
VowDOS='АаЕеЁёИиОоУуЫыЭэЮюЯя';
ConDOS='БбВвГгДдЖжЗзКкЛлМмНнПпРрСсТтФфХхЦцЧч';
IShDOS='Йй';
SHzDOS='ЪъЬь';
var
fIn:file of char;
fOu:text;
fName,s,t,w,Map:string;
c,d:char;
i:integer;
Vow,Con,ISh,SHz,Let:set of char;
Gap,Start:boolean;
begin
Write('Введите имя файла для форматирования: ');
ReadLn(fName);
{fName:='d.txt';}
Assign(fIn,fName);
ReSet(fIn);
Assign(fOu,'tst-ou-w.txt');
ReWrite(fOu);
Vow:=[];
Con:=[];
Ish:=[];
for i:=1 to Length(VowDOS) do Include(Vow,VowDOS[i]);
for i:=1 to Length(ConDOS) do Include(Con,ConDOS[i]);
for i:=1 to Length(IShDOS) do Include(ISh,IShDOS[i]);
for i:=1 to Length(SHzDOS) do Include(SHz,SHzDOS[i]);
Let:=Vow+Con+ISh+SHz;
s:='';
repeat
d:=#0;
while (Length(s)<Lx)and((d<>#$D)or(c<>#$A))and not EoF(fIn) do begin
if s=' ' then s:='';
d:=c;
Read(fIn,c);
if not (c in [#$D,#$A]) then s:=s+c;
end;
t:='';
if Length(s)=Lx then repeat
d:=c;
Read(fIn,c);
if not (c in [' ',#$D,#$A]) then t:=t+c;
until (c=' ')or((d=#$D)and(c=#$A))or(EoF(fIn));
if t<>'' then while not (s[Length(s)]=' ')or(Length(s)=0) do begin
Insert(s[Length(s)],t,1);
Delete(s,Length(s),1)
end;
{Rule #1}
if Length(t)>=4 then begin
for i:=1 to Length(t) do Map[i]:=Chr(i);
w:=t;
for i:=Length(t) downto 2 do {убираем Й после гласных в слове}
if (w[i] in ISh)and(w[i+1] in Vow) then begin
Delete(w,i,1);
Delete(Map,i,1)
end;
for i:=Length(w)-2 downto 2 do
if (w[i+1] in Vow)and(w[i] in Vow)and(w[i+2] in Let)and(w[i-1] in Con) then
if Length(s)+Ord(Map[i])<Lx then begin
s:=s+Copy(t,1,Ord(Map[i]))+'-';
Delete(t,1,Ord(Map[i]))
end;
end;
WriteLn(s);
s:=t;
if c=' ' then s:=s+' ';
{WriteLn(fOu,s)}
until EoF(fIn);
Close(fIn);
{ Close(fOu); }
;ReadLn
end.
Что-то не очень понимаю вот это место:
> И почему-то перед [i] ошибка №121
TP этого действительно не пропускает. Я думал, что ты уже перешла на FPC..
Для того, чтобы это скомпилить в TP, добавь тип string в определение конмтант, вот так:
VowDOS='АаЕеЁёИиОоУуЫыЭэЮюЯя';
ConDOS='БбВвГгДдЖжЗзКкЛлМмНнПпРрСсТтФфХхЦцЧч';
IShDOS='Йй';
SHzDOS='ЪъЬь';
Барахтаюсь
В FPC я тоже пробовала эту прогу, да он пропускает это место, но в результате непонятно что мне выдает, вот так
> В FPC я тоже пробовала эту прогу, да он пропускает это место,
> но в результате непонятно что мне выдает, вот так
Попытайся все же пердать словами, что именно она выдает..
Мне, например, она выдает примерно следующее:
VowDOS:srting='АаЕеЁёИиОоУуЫыЭэЮюЯя';
ConDOS:srting='БбВвГгДдЖжЗзКкЛлМмНнПпРрСсТтФфХхЦцЧч';
IShDOS:srting='Йй';
SHzDOS:srting='ЪъЬь';
В общем-то ничего и не выдает )) ( может быть я не туда смотрю конечно: надо в сам файл чтоли заглядывать потом?
)
Вот смотри что пишет:
> В общем-то ничего и не выдает ))
> ...
> Вот смотри что пишет:
> exitcode = 2
И это нынче называется "ничего не выдает"?.. Подруга подводоплавающая, это как раз и есть самая главная выдача! И значит она, что файл не найден.. Ты какой файл вводишь по запросу? мы, кажется, договорились на имена d.txt и w.txt. Пока прога работает только с досовской кодировкой, так что давай ей d.txt. И он должен быть в этой директории.. Ясно?
Теперь вообще FPC другую штуку пишет (типа ошибки, наверное, в новом окошке внизу)
А TP выдает ошибку №3 перед типом String, в штуке которую мы изменили.
УРА!!! Заработало
Там просто вместо string было srting написано, а я не проверила ...
Воть, честенько я невнимательностью страдаю к сожалению
Спасибки Алена
Lapp, хватит уже извиняться-то )) если бы не ты мне бы ноль в скором будущем поставили наверное
Поэтому спасибки большое
> Штучку прежнюю, где
> exited with
> exitcode = 2
> написано.
Файл лежит в той же директории и не читается?.. чудеса..
> Попробую продолжить в духе мессаджа #21
> Не думаю, конечно, что получится, но надо попробовать
Обязательно надо . Кроме шуток
Заметил еще одну квазиошибку в том своем тексте..
Закомментируй, плз, строчки:
Assign(fOu,'tst-ou-w.txt');
ReWrite(fOu);
Assign(fOu,'tst-ou-w.txt');
ReWrite(fOu);
Наверное "две идущие подряд согласные можно разделить, если перед первой из них стоит гласная, ..."
Пишу пояснения к реализации Правила №1 (см. пост №20)
Итак, к этому моменту у нас есть следующее:
- в переменной s лежит текущая строка (без последнего слова);
- в переменной t лежит последнее слово, которое нам как раз и надо разделить на части.
Во-первых, внимательно прочитав Пр.1, мы приходим к выводу, что в нем участвуют по крайней мере 4 буквы (две гласные, одна согласная перед ними и одна любая после них). Следовательно, для работы по Пр.1 нам нужны слова, которые содержат как минимум 4 буквы. Поэтому мы можем поставить условный оператор if, который будет фильтровать для нас все слова, давая только те, которые содержат не менее 4 букв:
if Length(t)>=4 then ...
w:=t;
for i:=Length(t) downto 2 do {убираем Й после гласных в слове}
if (w[i ] in ISh)and(w[i+1] in Vow) then begin {если за гласной идет Й}
Delete(w,i,1); {то убираем ее}
Delete(Map,i,1)
end;
Ура!!! Заработало, у меня перенеслось слово «выб-роси» из тех заумных мыслей мессаджа №17 с помощью второго правила, только там мягких и твердых знаков нету … )) (Но, я когда там мягкий знак приписывала все получалось)
Вот программа, только, наверное, в ней надо что-то поменять, а то повторяется несколько строчек в конце:
{for Lapp by Gold_Fish : ) )) }
Program May;
const
Lx=37;
VowDOS:string='АаЕеЁёИиОоУуЫыЭэЮюЯя';
ConDOS:string='БбВвГгДдЖжЗзКкЛлМмНнПпРрСсТтФфХхЦцЧч';
IShDOS:string='Йй';
SHzDOS:string='ЪъЬь';
var
fIn:file of char;
fOu:text;
fName,s,t,w,Map:string;
c,d:char;
i:integer;
Vow,Con,ISh,SHz,Let:set of char;
Gap,Start:boolean;
begin
Write('Введите имя файла для форматирования: ');
ReadLn(fName);
{fName:='d.txt';}
Assign(fIn,fName);
ReSet(fIn);
Assign(fOu,'tst-ou-w.txt');
ReWrite(fOu);
Vow:=[];
Con:=[];
Ish:=[];
for i:=1 to Length(VowDOS) do Include(Vow,VowDOS[i]);
for i:=1 to Length(ConDOS) do Include(Con,ConDOS[i]);
for i:=1 to Length(IShDOS) do Include(ISh,IShDOS[i]);
for i:=1 to Length(SHzDOS) do Include(SHz,SHzDOS[i]);
Let:=Vow+Con+ISh+SHz;
s:='';
repeat
d:=#0;
while (Length(s)<Lx)and((d<>#$D)or(c<>#$A))and not EoF(fIn) do begin
if s=' ' then s:='';
d:=c;
Read(fIn,c);
if not (c in [#$D,#$A]) then s:=s+c;
end;
t:='';
if Length(s)=Lx then repeat
d:=c;
Read(fIn,c);
if not (c in [' ',#$D,#$A]) then t:=t+c;
until (c=' ')or((d=#$D)and(c=#$A))or(EoF(fIn));
if t<>'' then while not (s[Length(s)]=' ')or(Length(s)=0) do begin
Insert(s[Length(s)],t,1);
Delete(s,Length(s),1)
end;
{Rule #1}
if Length(t)>=4 then begin
for i:=1 to Length(t) do Map[i]:=Chr(i);
w:=t;
for i:=Length(t) downto 2 do {убираем Й после гласных в слове}
if (w[i] in ISh)and(w[i+1] in Vow) then begin
Delete(w,i,1);
Delete(Map,i,1)
end;
for i:=Length(w)-2 downto 2 do
if (w[i+1] in Vow)and(w[i] in Vow)and(w[i+2] in Let)and(w[i-1] in Con) then
if Length(s)+Ord(Map[i])<Lx then begin
s:=s+Copy(t,1,Ord(Map[i]))+'-';
Delete(t,1,Ord(Map[i]))
end;
end;
if (w[i] in SHz) and (w[i+1] in Con) then begin
Delete(w,i,1);
Delete(Map,i,1)
end;
for i:=Length(w)-2 downto 2 do
if (w[i+1] in Con) and (w[i] in Con) and (w[i+2] in Let) and (w[i-1] in Vow) then
if Length(s)+Ord(Map[i])<Lx then begin
s:=s+Copy(t,1,Ord(Map[i]))+'-';
Delete(t,1,Ord(Map[i]))
end;
WriteLn(s);
s:=t;
if c=' ' then s:=s+' ';
{WriteLn(fOu,s)}
until EoF(fIn);
Close(fIn);
{ Close(fOu); }
;ReadLn
end.
Подскажите пожалуйста, как задать момент, когда вторая часть слова содержит хотя бы одну гласную???
> Ура!!! Заработало,
Правда приятно, когда сам что-нить сделаешь и.. работает!! Ни с чем несравнимое чувство..
> у меня перенеслось слово «выб-роси»
Да, видел. Congratulations!
Но, к сожалению, из этой фразы я делаю вывод, что ты не пыталась менять значение константы Lx. Меняя ее, ты можешь регулировать длину строки и прогонять снова, получая много маленьких радостей.. Или огорчений, если обнаружатся ошибки.. Ошибки есть всегда, увы - это закон. Вот, например:
> только там мягких и твердых знаков нету … ))
> (Но, я когда там мягкий знак приписывала все получалось)
- это странно. В обработке карты Map у меня была ошибка (сейчас исправлено), в результате нее мягкий знак переносился на следующую строчку, что, ессно, неправильно.
Но все же, ты молодец. В целом ты произвела правильные действия, хотя и не все..
Во-первых, нужно было взять больший кусок, включая копирование t в w (как же иначе? мы же испортили w, когда обработали его первым правилом).
Во-вторых, нужно было организовать выбор из результатов, полученных по Пр.1 и Пр.2. Не применять их сразу очертя голову, а выяснить, какой из двух предлагаемых переносов лучше (если слово допускает оба переноса, и 1, и 2 типа). Я ввел соответствующий механизм, основанный на массиве Cuts размера 3 (по числу правил), который содержит длины первой части слова (оставляемой на старой строке). Короче, ошибки были, но я доволен тем, что ты сделала . Респект!
Тепрь дальше по делу.
В первую очередь - мой должок. Я говорил о том, что в алгоритме Пр.1 есть ошибка. Исправляю ее.
Дело в том, что проверка на минимальную длину слова должна стоять после выбрасывания Й (или мягких и твердых знаков в Пр.2). Иначе после выбрасывания длина слова может сократиться до 3 букв, что приведет к ошибкам. Сейчас это исправлено (посмотри, сравни новый и старый коды).
Кроме этого, я нашел и исправил еще пару ошибок (не пугайся, у себя ). О первой я уже сказал в самом начале (посмотри и найди отличия в операторе IF после проверки правила, обоих из них). А вторая ошибка состояла в том, что я не прекращал разбор слова после того, как разрез, подходящий по длине, был уже найден. Это приводило к тому, что при нахождении еще одного разреза перенос получался более короткий. Я исправил это вставлением оператора Break, который прекращает выполнение цикла (найди оба места места, где стоит Break и разбери подробно).
Еще одно исправление. Хотя это не ошибка, но все же было некрасиво. Карта Map у меня была раньше строкой, хотя я использовал ее для хранения чисел. Сейчас я сделал ее обычным массивом. Это привело, например, к невозможности использования процедуры Delete с ней, но это особо и не нужно (заменил циклом, посмотри).
> Подскажите пожалуйста, как задать момент, когда
> вторая часть слова содержит хотя бы одну гласную???
Замечательный вопрос, он показывает, что уровень твоего понимания достаточно высокий . Нет, в самом деле - прогресс налицо!
Подсказываю. Я завел некий флаг (булева переменная Flag, найди ее в определении переменных), которой снячала присваиваю значений false (ложь), то есть флаг сброшен. В цикле перебора букв слова я присваиваю ей саму себя ИЛИ результат проверки буквы на гласность. То есть она будет оставаться false до тех пор, пока все буквы согласные (оба параметра ложные), но при первой гласной ей присвоится значение true (правда), и оно уже не сбросится, потому что первый операнд (то есть она сама) операции OR всегда будет с этих пор true. То есть флажок как бы встает при встрече гласной и больше не падает. После этого я использую Flag в логическом выражении для Пр.2. Разбери все это внимательно и убедись, что поняла - или задавай вопросы..
Давай - изучай, разбирайся - и продвигайся дальше! Правило 3 на очереди..
Успеха!
PS
Мне кажется, удобно было бы устроить запрос длины строки (Lx) от пользователя. Сможешь сделать?
{ Hyphenation
Version 0.5
- choosing the right cut
- rule #2
- rule #1
- getting the last word in a line
- reading the file
for Gold_Fish by Lapp }
Program May;
const
Lx=78;
VowDOS:string='АаЕеЁёИиОоУуЫыЭэЮюЯя';
ConDOS:string='БбВвГгДдЖжЗзКкЛлМмНнПпРрСсТтФфХхЦцЧч';
IShDOS:string='Йй';
SHzDOS:string='ЪъЬь';
var
fIn:file of char;
fOu:text;
fName,s,t,w,Map:string;
c,d:char;
i,Cut:integer;
Vow,Con,ISh,SHz,Let:set of char;
Gap,Start,Flag:boolean;
Cuts:array[1..3]of integer;
begin
Write('Введите имя файла для форматирования: ');
ReadLn(fName);
{fName:='d.txt';}
Assign(fIn,fName);
ReSet(fIn);
Assign(fOu,'tst-ou-w.txt');
ReWrite(fOu);
Vow:=[];
Con:=[];
Ish:=[];
for i:=1 to Length(VowDOS) do Include(Vow,VowDOS[i]);
for i:=1 to Length(ConDOS) do Include(Con,ConDOS[i]);
for i:=1 to Length(IShDOS) do Include(ISh,IShDOS[i]);
for i:=1 to Length(SHzDOS) do Include(SHz,SHzDOS[i]);
Let:=Vow+Con+ISh+SHz;
s:='';
for i:=1 to Lx do Write('-');
WriteLn;
repeat
for i:=1 to 3 do Cuts[i]:=0;
d:=#0;
while (Length(s)<Lx)and((d<>#$D)or(c<>#$A))and not EoF(fIn) do begin
if s=' ' then s:='';
d:=c;
Read(fIn,c);
if not (c in [#$D,#$A]) then s:=s+c;
end;
t:='';
if Length(s)=Lx then repeat
d:=c;
Read(fIn,c);
if not (c in [' ',#$D,#$A]) then t:=t+c;
until (c=' ')or((d=#$D)and(c=#$A))or(EoF(fIn));
if t<>'' then while not (s[Length(s)]=' ')or(Length(s)=0) do begin
Insert(s[Length(s)],t,1);
Delete(s,Length(s),1)
end;
{Rule #1}
Map:='';
for i:=1 to Length(t) do Map:=Map+Chr(i);
w:=t;
for i:=Length(t) downto 2 do {убираем Й после гласных в слове}
if (w[i] in ISh)and(w[i+1] in Vow) then begin
Delete(w,i,1);
Delete(Map,i,1)
end;
if Length(w)>=4 then
for i:=Length(w)-2 downto 2 do
if (w[i+1] in Vow)and(w[i] in Vow)and(w[i+2] in Let)and(w[i-1] in Con) then
if Length(s)+Ord(Map[i])<Lx then begin
Cuts[1]:=Ord(Map[i+1])-1;
Break
end;
{Rule #2}
Map:='';
for i:=1 to Length(t) do Map:=Map+Chr(i);
w:=t;
for i:=Length(t) downto 2 do {убираем Ъ и Ь после согласных в слове}
if (w[i] in SHz) and (w[i+1] in Con) then begin
Delete(w,i,1);
Delete(Map,i,1)
end;
if Length(w)>=4 then begin
Flag:=false;
for i:=Length(w)-2 downto 2 do begin
Flag:=Flag or(w[i+2] in Vow);
if (w[i+1] in Con)and(w[i] in Con)and(w[i-1] in Vow)and Flag then
if Length(s)+Ord(Map[i])<Lx then begin
Cuts[2]:=Ord(Map[i+1])-1;
Break
end
end
end;
{Выбор из всех разрезов самого длинного}
Cut:=0;
for i:=1 to 3 do if Cuts[i]>Cut then Cut:=Cuts[i];
{Собственно разрез строки}
if Cut>0 then begin
s:=s+Copy(t,1,Cut)+'-';
Delete(t,1,Cut)
end;
{Вывод текста}
WriteLn(s);
s:=t;
if c=' ' then s:=s+' ';
{WriteLn(fOu,s)}
until EoF(fIn);
Close(fIn);
{ Close(fOu); }
;ReadLn
end.
Спасибки
Rule №3:
if ((w[i] in Vow) and ((w[i-1] in Con) or (w[i-1] in Vow))) and ({все равно не поняла
как задать тут что есть гласная во второй части}) then
if Length(s)+Ord(Map[i])<Lx then begin
s:=s+Copy(t,1,Ord(Map[i]))+'-';
Delete(t,1,Ord(Map[i]))
end;
М | для программных кусков используй не quote, а code=pas! Lapp |
Вот тут:
Rule №3:
if ((w[i] in Vow) and ((w[i-1] in Con) or (w[i-1] in Vow))) and ({все равно не поняла
как задать тут что есть гласная во второй части}) then
if Length(s)+Ord(Map[i])<Lx then begin
s:=s+Copy(t,1,Ord(Map[i]))+'-';
Delete(t,1,Ord(Map[i]))
end;
Я разбиралась, а все равно не поняла, а вторник - это очень поздно
Gold_Fish, мне искренне жаль, что это оказалось непосильным для тебя. Я судил по твоим мессаджам и полагал, что если ты чего-то не знаешь - ты спросишь. Но ты спрашивала очень мало, из чего я заключил, что тебе все понятно. Хочу тебе сказать на будущее - не обязательно на этом форуме:
1. обязательно задавай конкретные вопросы, что именно не понятно;
2. вникай каак можно глубже во все, что тебе присылают в ответ;
3. если остались неясности - переходи снова к п.1.
Если хотя бы одно из этих условий не выполнено, то толку не будет. И это очень обидно..
У меня уже есть сейчас полный рабочий вариант программы, реализующий все три правила. А у тебя есть последняя возможность все-таки разобраться в задаче. Покажи свои попытки продвинуться. Скажи, что именно вызвало затруднения, что неясно. Вместе разберемся..
Давай, жду.
Да все уже, сдала я ))
Вторую делаю к зачету уже ))
Огромное Спасибки за помощь