Помощь - Поиск - Пользователи - Календарь
Полная версия: Перенос слова
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Страницы: 1, 2
Gold_Fish
Помогите, пожалуйста, очень прошу, хотя бы частично:
Перенос слова. Перенос русского слова с одной строки на другую с большей вероятностью выполняется правильно, если пользоваться следующими правилами:
1)две идущие подряд гласные можно разделить, если перед первой из них стоит согласная, а за второй идет хотя бы одна буква (буква й при этом рассматривается вместе с предшествующей ей гласной как единое целое);
2) две идущие подряд согласные можно разделить, если первой из них стоит гласная, а в той части слова, которая идет за второй согласной, имеется хотя бы одна гласная (буквы ь, ъ вместе с предшествующей согласной рассматриваются как единое целое);
3) если не удается применить первые два правила, то слово разбивают так, чтобы первая часть содержала более чем одну букву и оканчивалась на гласную, а вторая содержала хотя бы одну гласную.
Дан текст, состоящий из нескольких строк. Преобразовать текст таким образом, чтобы длина строк не превышала заданного значения, используя при этом перенос слов. blink.gif

Как найти ближайший к концу строки пробел, если при заданном значении слово "как бы разбивается"? Как осуществить на Паскале приведенный выше перенос???
Lapp
Цитата(Gold_Fish @ 5.12.2006 21:54) *

Дан текст, состоящий из нескольких строк. Преобразовать текст таким образом, чтобы длина строк не превышала заданного значения, используя при этом перенос слов. blink.gif

Как найти ближайший к концу строки пробел, если при заданном значении слово "как бы разбивается"? Как осуществить на Паскале приведенный выше перенос???

Первый и главный вопрос к тебе: знаки препинания не нужно учитывать? Это ведь тоже непростой вопрос. Например, обычно их нельзя переносить (отрывать от слова). А тире, скажем, отделяется от слова пробелом, но переносить его при этом тоже не стОит. Есть многосимвольные знаки препинания (... , ?.. , !.. , ..). И нужно ли сохранять пробелы в конце строки (впрочем, это, наверное, нет). Еще, есть такой особый знак препинания, как "красная строка", например.. Короче, ответь.

Второй вопрос.. Не совсем понятен пункт 1. Правильно я понимаю, что в соответствии с ним слова "параноик", "наитие", "кондуит" нельзя перенести так: парано-ик, на-итие, конду-ит?

Если пока забыть про знаки препинания и остальные проблемы, то начать можно примерно так..
От начала текста отмеряем максимальную длину строки (Lx) и смотрим, попадает ли разрыв в тело слова. Признаком этого можно считать наличие букв (а не пробелов, знаков препинания..) по обе стороны от разрыва. Вот я тут набросал примерный текст программки, которая берет в отдельную строку s слово, попавшее на разрыв. Дальше можно с ним развлекаться и смотреть, как его можно делить. Моя программа делает это пока только по урезанному первому правилу для, так сказать, демонстрации smile.gif. Если прояснятся вышеупомянутые вопросы, могу поучаствовать и в дальнейшем развитии проги. Задачка интересная smile.gif. Интересно, где такие задают? smile.gif
{ 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.

Забыл сказать: я использую пока английские буквы, иначе говоря латиницу, во избежание сложностей. Потом можно будет перейти на настоящий русский. Соответствие букв в основном понятно, надеюсь. Кроме обычных еще есть Q как Я и W как Ю.
Текст пока в массиве, потом, видимо, нужно будет читать из файла..
Gold_Fish
blink.gif Ой, неужели кто-то мне помог!!! Спасибо Iapp огромное, преогромное!!! give_rose.gif
Насчет пункта №1: извиняюсь, не так немножко, там буква й при этом рассматривается вместе с предшествующей ей гласной как единое целое (я полагаю, что если перед й стоит гласная, то они рассматриваются как единое целое).
А вот, про знаки препинания не знаю, так как в задаче ничего не сказано.
Задают такие задачи в Ивановском Государственном Энергетическом Университете на 1 курсе, факультета ИВТФ.
Помогите доделать, пожалуйста. unsure.gif
Lapp
Цитата(Gold_Fish @ 6.12.2006 15:48) *

Помогите доделать, пожалуйста. unsure.gif

Помочь - не проблема smile.gif.
Но ты сначала разберись в том, что есть, и покажи, что разобралась.
Твой ход.

Значит, в Энергетическом.. smile.gif Хм, забавно. Я все же думал, что что-то более близкое к гуманитарной области. Но все равно приятно такое видеть - особенно на фоне повального "удаффа" и не только. А уж про перенос стали забывать даже в книгопечатаньи..

и - Lapp я.. Лопарь. smile.gif
Gold_Fish
Я знаю, что Lapp, я даже сначала так написала, а потом посмотрела внимательнее на ник, ведь там же Iapp написано, вот и исправила smile.gif
Ну так вот, ввожу я уже свой текст:
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.


А как же мне сделать, чтобы остальные слова и часть перенесенного слова печатались на новой строке??? nea.gif
Lapp
Цитата(Gold_Fish @ 6.12.2006 18:07) *

Ну так вот, ввожу я уже свой текст:

Хорошо, что вводишь. Но только..
1. Почему в программе исчезло все форматирование? Я имею в виду сдвиги. У меня все было аккуратно. Учти, это очень важно. И еще учти, что я не хочу тратить вреям на восстановление форматирования вручную каждый раз! Будь добра, сохраняй его, а также сама старайся писать правильно..
2. Когда постишь прогу, используй теги Паскаля (выбери в выпадающем меню со словом CODE над окном ввода). Опять же, я постоянно исправлять не намерен (это я уже как админ тебе говорю).
Цитата(Gold_Fish @ 6.12.2006 18:07) *

А как же мне сделать, чтобы остальные слова и часть перенесенного слова печатались на новой строке??? nea.gif

Не спеши.. Все будет..
Как я уже говорил, та программа была нацелена не на решение поставленной задачи, а на демонстрацию методов. Теперь, когда все более-менее прояснилось, можно начать систематически решать проблему.. Для этого начнем все заново. Ты готова? Шаг за шагом разберемся во всем и подойдем к решению. По пути задавай вопросы, если что непонятно. Если сразу все ясно - пиши свой вариант smile.gif
Согласна с таким подходом? Пока считаю, что Да, согласна (но ты все же ответь), и начинаю продолжать smile.gif.

Сначала разберемся с вводом текста. Думаю, ввод надо осуществлять из файла. Причем, поскольку в нормальном обычном тексте длина строки может быть больше 255 символов (макимальный размер переменной String) - в последнее время принято, что строка равна абзацу -, то использование строк во входном потоке отпадает. Я написал кусок кода, который пока читает входной файл и просто режет его на куски длины Lx (сейчас задано 30). При этом оригинальные концы строк (то есть концы абзацев) сохраняются. Посмотри, как он устроен, разберись и тогда пойдем дальше. Обрати внимание, как обрабатываются концы строк (абзацев) при чтении (в файле строки разделяются последовательностью двух символов: #13,#10).

Дальше, теперь переходим на настоящий русский - никаких латиниц. Это влечет за собой несколько трудностей.
Русских кодировок не одна, а несколько. Как минимум три: windows-1251, DOS-866 и KOI8-R (есть и еще). В настоящее время самой распространенной является первая, сокращенно Win. Но TP и BP используют кодировку DOS. Поскольку для нас существенно расположение гласных, а оно определенно зависит от кодировки, то игнорировать этот вопрос нельзя. Выходов как минимум три:
- выбрать одну кодировку и ей ограничиться;
- при вводе файла запрашивать от пользователя ввод кодировки;
- распознавать кодировку автоматически.
Мне больше всего нравится 3-й способ, но он не 100% надежен, кроме того может быть труден для начинающего (сорри, -щей..), так что предлагаю выбрать второй вариант. В моем куске кода есть наборы гласных для Win и DOS кодировок, хотя я не уверен, что тебе удастся из правильно скопировать.
Для копирования файлов и текстов очень рекомендую использовать программку Far. Знакома ты с ней? Ответь, пожалуйста.

Ладно, пока хватит. Вот код. Постарайся, чтоб при копировании русские буквы не превратились в белиберду. Обязательно скажи, удалось ли тебе это.
{ 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.

Цитата(Gold_Fish @ 6.12.2006 18:07) *

посмотрела внимательнее на ник, ведь там же Iapp написано, вот и исправила smile.gif

нет, там было маленькое L (l). Сейчас я исправил на большое.. smile.gif
Gold_Fish
Спасибки, Lapp smile.gif
Почти все дошло, кроме:
почему пишет что begin не хватает в:
Цитата
Vowels_Win:set of char=
['А','а','Е','е','Ё','ё','И','и','О','о','У','у','Ы','ы','Э','э','Ю','ю','Я','я'];
Vowels_DOS:set of char=
['_',' ',':','_','р','с','_','Ё','_','R','"','г','>','л','_','н','_','о','_','п'];

и почему то на русский алфавит мой Паскаль не переходит, хотя у него и справка русская. Да, и если поставить Begin, то выдает потом ошибку №3.
Еще не оч поняла смысл этой аброкадабры, вернее её перевод:
Цитата
Write(''ў_¤Ёв_ Ё┐п д c< ¤<п дRа┐ вЁаRў -Ёп: ');

И в [#$0D,#$0A] выдает тоже ошибку, почему?
и что такое EoF? blink.gif
tst-ou-w.txt - это я так понимаю имя файла, а мне его заранее создать придется?
Цитата

Для копирования файлов и текстов очень рекомендую использовать программку Far. Знакома ты с ней? Ответь, пожалуйста.

Нет
Цитата
Постарайся, чтоб при копировании русские буквы не превратились в белиберду. Обязательно скажи, удалось ли тебе это.

Никак у меня с русскими не получается, он не хочет почему-то переключаться на русский текст... nea.gif
А так суть остального и предназначения я поняла smile.gif
Ой сколько я много вопросов накатала, извиняюсь, но так вышло smile.gif
Ответьте пожалуйста, заранее спасибо smile.gif
Lapp
Gold_Fish, извини, я неправильно (не в той кодировке запостил прогу, каюсь.. Впредь буду внимательнее.

> почему пишет что begin не хватает в:
...
> И в [#$0D,#$0A] выдает тоже ошибку, почему?
Вот это я не знаю.. пробовал смоделировать разными способами - не вышло. Будем надеяться, что оно пройдет в правильной кодировке, либо вернемся к этому потом еще раз.

> и что такое EoF?
Это признак конца файла (End of File). Это функция, которая возвращает false покак конец не достигнут, а потом true. В данном случае чтение из файла продолжается до обнаружения его конца.

> tst-ou-w.txt - это я так понимаю имя файла, а мне его заранее создать придется?
Заранее не надо, это выходной файл, он сам создается заново. Имя можно изменить, как тебе нравится, или вообще запрашивать юзера имя выходного файла, как запрашиваем имя входного.

> Никак у меня с русскими не получается, он не хочет почему-то
> переключаться на русский текст... nea.gif
В Паскале, если это 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, нажми там все Ок, а потом перезапусти Фар.
Дальше объясню, когда подтвердишь установку..

> А так суть остального и предназначения я поняла smile.gif
Вот и славненько..

> Ой сколько я много вопросов накатала, извиняюсь, но так вышло smile.gif
Задавай сколько хочешь. Главное - чтоб поняла smile.gif
Ниже помещаю текст программы в правильной кодировке. Но если ты его будешь копировать из браузера через notepad, то русского все равно не будет. Нужен Far. Ясно?
Ну, давай, успехов тебе.. smile.gif
{ 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.
Pola
Цитата(Gold_Fish @ 7.12.2006 21:49) *

Спасибки, Lapp smile.gif
Почти все дошло, кроме:
почему пишет что begin не хватает в:

Может const не скопировала?
Gold_Fish
Из браузера я не копирую, а сама перепечатываю в Паскаль, мне так разобраться легче smile.gif
Цитата
Ну, давай, успехов тебе..

Спасибки, сейчас буду разбираться smile.gif
Ах, да, я на своем компе работаю smile.gif
И ещё:
Цитата
И чтобы правильно копировать файлы, я настоятельно рекомендую тебе установить Far. Я тебя спрашивал о нем раньше, но ты деликатно промолчала.

Я писала, что не знакома с этой прогой no1.gif
Я вспомнила у меня папа всегда ей пользуется, но она у него какая-то древняя smile.gif , поэтому я её не открываю

Цитата(Pola @ 8.12.2006 11:16) *

Может const не скопировала?

Не, я писала const unsure.gif
Lapp
Цитата(Gold_Fish @ 8.12.2006 16:45) *

Из браузера я не копирую, а сама перепечатываю в Паскаль, мне так разобраться легче smile.gif
...
Я вспомнила у меня папа всегда ей пользуется,

Сама перепечатываешь - это хорошо, но внимание удвой, как минимум.. Одна точка вместо запятой - и все в тартарары.. smile.gif
Отлично! вот папа будет рад, что ты у него будешь консультироваться.. smile.gif)
Она выглядит как старый добрый Нортон, потому и кажется древней. Но она внутри молодая! smile.gif))))
Gold_Fish
Я установила новый, т к в старом Windows-1251.reg не было, надеюсь мне папа ничего не сделает smile.gif)) , а что дальше?
Насчет внимательности, это да, стараюсь внимательно делать smile.gif
Gold_Fish
Страничка freepascal.org не хочет открываться blink.gif
Lapp
Цитата(Gold_Fish @ 8.12.2006 17:18) *

Я установила новый, т к в старом Windows-1251.reg не было, надеюсь мне папа ничего не сделает smile.gif)) , а что дальше?
Насчет внимательности, это да, стараюсь внимательно делать smile.gif

Cool! Дальше так..
Навигация там простая - две независимых панели, переключение между ними клавишей Tab, работать можешь на любой. Полоска, выбирающая активный файл, двигается стрелками (рекомендую оставить мышь отдыхать). F9 выводит в некое меню, где, например, можно настроить вид панелей (рекомендую Full). Запомнить настройки - Shift-F9. Все основные команды (копировать, двигать, удалять..) на F-клавишах, рекомендую запомнить основные (внизу есть подсказка для них, реагирующая на нажатие Shif и Alt). Копирование файлов обычно происходит между панелями, но можно указать любой путь вручную. Запуск на выполнение - Enter, также и вход в поддиректории. Две точки на верхней строчке (есть во всех директориях, кроме корневых на дисках) - это выход наверх (стандартное обозначение в DOS и UNIX). Просмотр внутренностей любого файла - F3.

Что нам сейчас важно, это его встроенный редактор. Сделаем одно полезное
Упражнение:
Скопировать программный текст из окна браузера (то бишь, отсюда) в файл так, чтоб не испортить русский текст (строковые константы и комментарии).
Выполняем:
1. Забрать нужный текст в браузере в буфер (закрасить курсором, нажать Ctrl-C).
2. В Фаре зайти в нужную директорию (или создать новую - F7 - и зайти в нее).
3. Нажать Shift-F4 (открытие нового файла для редактирования). На запрос имени ввести желаемое имя (оно должно иметь расширение pas, если это паскалевская прога - например, hyphen.pas).
4. Убедись, что текущая кодировка - DOS. Она обозначена сверху, примерно в серединке. Если там написано Win или еще что-то, нажми клавишу F8 - при этом эта кодировка должна меняться между DOS и Win (другие установленные кодировки можно выбрать по Shif-F8). Примечание: этот пункт зависит от того, установила ли ты таблицы, как я просил тя в предыдущем мессадже.
5. Если ты уверена, что кодировка есть DOS, делай paste (как обычно, Ctrl-V). Скопированный из браузера текст при этом должен вставиться. Чтобы деселектить блок, можешь нажать Ctrl-U, но это не важно.
6. Записать файл на диск (F2, смотри подсказку на нижней строчке).
7. Выйти (Esc).
Созданный таким образом файл можно теперь загрузить в редактор TP (или FPC, если скачаешь). Проверь, сохранились ли русские буквы и рапортуй smile.gif
Цитата(Gold_Fish @ 8.12.2006 17:34) *

Страничка freepascal.org не хочет открываться blink.gif

Это жесть.. sad.gif
А ты правда готова качать 28 мег?.. Какой у тя коннекшн? На диалапе при всех самых благоприятных обстоятельствах (что бывает редко) это займет не меньше полутора часов.. Но оно того стОит! smile.gif
Вот прямой линк на файл на русском зеркале:
ftp://ftp.chg.ru/pub/lang/pascal/fpc/dist....i386-win32.exe
- надеюсь, он сработает..
Ну, давай.. smile.gif
Gold_Fish
Цитата(Lapp @ 9.12.2006 5:18) *

А ты правда готова качать 28 мег?.. Какой у тя коннекшн? На диалапе при всех самых благоприятных обстоятельствах (что бывает редко) это займет не меньше полутора часов.. Но оно того стОит! smile.gif
Вот прямой линк на файл на русском зеркале:
ftp://ftp.chg.ru/pub/lang/pascal/fpc/dist....i386-win32.exe
- надеюсь, он сработает..
Ну, давай.. smile.gif

Вот, если чесно мне уже все равно как долго его качать, лишь бы сделать задачу быстрее, сдавать надо, а у меня не сделано mega_chok.gif
Gold_Fish
Премногоуважаемый Lapp! smile.gif))
Я создала обычный вордовский файл, там написала текст, и все smile.gif)) И все равно не так, что делать?
Lapp
Цитата(Gold_Fish @ 9.12.2006 13:52) *

Премногоуважаемый Lapp! smile.gif))
Я создала обычный вордовский файл, там написала текст, и все smile.gif)) И все равно не так, что делать?

Милейшая исполнительница желаний безумных старух, Вы создали, извиняюсь-с - doc-файл?.. smile.gif
Дружок, пойди в неказистый синенький Фар, создай там в рабочей твоей директории новый файл - назови, скажем, d.txt. Убедись, однако, что кодировка состоит DOS и сокопируй туда вот этот самовый бред.. сорри, вот эти мои заумные мысли - да, да, прямо отсюда. Да и сохрани его, да и закрой степенно..
Затем, нимало не отдыхаша, открой на редактирование еще один новый файл - и нареки имя ему w.txt. Закокококо.. кхм-кхм.. закопируй туда то же самое, но только в этот раз да вразумит тебя святой Пингвин, покровитель всех программеров, соблюсти кодировку при значении Win (рубильник F8 на твоем распределительном щитке) - да установи оное значение ДО копирования, противу сказать опосля..
И етути двое фалОв да будут отныне для тя тестовыми, ако в транслейшне - попробовательными..
А о сатнинском Word'е - и думать забудь, и трогать его не смей, и выброси его в геенну огненную, и - самое главное - НИКОГДА НЕ смотри в нутро поганое файла того, что создала ты в нем (переключатель F3 (просмотр файла в Фаре) и не трогай даже! ну, если тронешь - ну, сходи руки помой smile.gif )
O'kay???..
Gold_Fish
Здраствуйте, друг мой Lapp! smile.gif)) (Снова Вас тревожит исполнительница желаний безумных старух) smile.gif))
Все я сделала как Вы указали,
будьте так любезны, скажите, что дальше нужно делать? rolleyes.gif
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.
Gold_Fish
smile.gif Более или менее все понятно, а вот куда впихнуть буквы "й, ь, ъ" для них просто массив создать в начале, да? rolleyes.gif
P. S. Дальше не могу продвинуться, никак не составлю условие для переноса wacko.gif
Програмка прикольно работает, так интересно переносит твои, как ты выразился
Цитата
вот эти мои заумные мысли

lol.gif
Lapp
Вот, есть первый ощутимый результат smile.gif.
Я реализовал первое правило. Получается не так просто, чтобы объяснить в двух словах. Давай, лучше ты посмотришь и станешь задавать вопросы - по сделанному, а не "как дальше".. Я немного подозреваю, что ты смотришь на сделанное, как на пройденный этап, к которому нет смысла возвроащаться.. А это неправильно, так как именно в этом и состоит твой прогресс. Если можешь, развей мои подозрения smile.gif.

В принципе, реализация остальных правил может быть проведена по образу и подобию первого. Так что если ты действительно разберешься, ты сможешь это сделать. Извини за отстутствие комментариев, могу добавить позже..

> Более или менее все понятно, а вот куда впихнуть буквы "й, ь, ъ"
> для них просто массив создать в начале, да?
Я вообще несколько переделал организацию ввода алфавита. Ну, увидишь, как. Это для простоты, компактности и лучшей читаемости (да и писаемости тоже smile.gif) кода, особенно когда несколько кодировок.

> P. S. Дальше не могу продвинуться, никак не составлю условие для переноса wacko.gif
Вот, я его составил smile.gif. Enjoy! smile.gif

Последние замечания:
- вывод пока идет только на экран;
- длина строки задается 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.
Gold_Fish
Цитата
Я немного подозреваю, что ты смотришь на сделанное, как на пройденный этап, к которому нет смысла возвроащаться.. А это неправильно, так как именно в этом и состоит твой прогресс. Если можешь, развей мои подозрения smile.gif

Сейчас разберусь в проге и попробую развеять smile.gif))
И спасибо Сударь, благодаря Вам я плавно приближаюсь к окончанию первого семестра моего учения, благодаря Вашей бескорыстной помощи give_rose.gif
Gold_Fish
Что-то не очень понимаю вот это место:
Цитата
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]);

И почему-то перед [i] ошибка №121 unsure.gif
Что тогда значит "i" ? wacko.gif
Ещё вот это можно пояснить:
Цитата
s:=s+Copy(t,1,Ord(Map[i]))+'-';

Что такое тут Copy(t,1,Ord(Map[i])) ? blink.gif
Lapp
> И почему-то перед [i] ошибка №121 unsure.gif
TP этого действительно не пропускает. Я думал, что ты уже перешла на FPC..
Для того, чтобы это скомпилить в TP, добавь тип string в определение конмтант, вот так:
  VowDOS='АаЕеЁёИиОоУуЫыЭэЮюЯя';
ConDOS='БбВвГгДдЖжЗзКкЛлМмНнПпРрСсТтФфХхЦцЧч';
IShDOS='Йй';
SHzDOS='ЪъЬь';


> Что-то не очень понимаю вот это место:
> for i:=1 to Length(VowDOS) do Include(Vow,VowDOS[i]);
> ...
Это заполнение множеств. Раньше я задавал их непосредственно (см. старый вариант проги), а сейчас через строчку-константу. Так удобнее, согласись. Правда, требует лишних операторов (вот этих).

> Что тогда значит "i" ? wacko.gif
Это переменная цикла. См. описание цикла FOR в документации. Рекомендую описание:
http://download.excode.ru/download277.html

> Что такое тут Copy(t,1,Ord(Map[i])) ? blink.gif
Копирование части строки. В указанном документе см. Приложение 4, Модуль System, П 4.1.3.

Давай, Рыбка - барахтайся, а то утонешь! smile.gif
Gold_Fish
Барахтаюсь lol.gif
В FPC я тоже пробовала эту прогу, да он пропускает это место, но в результате непонятно что мне выдает, вот так nea.gif
Цитата
Для того, чтобы это скомпилить в TP, добавь тип string в определение конмтант

А можно попроще для меня сказать еще раз? rolleyes.gif
Lapp
> В FPC я тоже пробовала эту прогу, да он пропускает это место,
> но в результате непонятно что мне выдает, вот так
Попытайся все же пердать словами, что именно она выдает..
Мне, например, она выдает примерно следующее:
Цитата
C:\Home\home\ak\_pas\_t\t056_Gold_Fish>t056-4.exe
Введите имя файла для форматирования: d.txt
Милейшая исполнительница желаний
безумных старух, Вы создали, извиня-
юсь-с - doc-файл?..
Дружок, пойди в неказистый синенький
Фар, создай там в рабочей твоей
директории новый файл - назови,
скажем, d.txt. Убедись, однако, что
кодировка состоит DOS и сокопируй
туда вот этот самовый бред.. сорри,
вот эти мои заумные мысли - да, да,
прямо отсюда. Да и сохрани его, да и
закрой степенно..
Затем, нимало не отдыхаша, открой на
редактирование еще один новый файл -
и нареки имя ему w.txt. Закокококо..
кхм-кхм.. закопируй туда то же самое,
но только в этот раз да вразумит тебя
святой Пингвин, покровитель всех
программеров, соблюсти кодировку при
значении Win (рубильник F8 на твоем
распределительном щитке) - да
установи оное значение ДО
копирования, противу сказать опосля..
И етути двое фалОв да будут отныне
для тя тестовыми, ако в транслейшне -
попробовательными..
А о сатнинском Word'е - и думать
забудь, и трогать его не смей, и
выброси его в геенну огненную, и -
самое главное - НИКОГДА НЕ смотри в
нутро поганое файла того, что создала
ты в нем (переключатель F3 (просмотр
файла в Фаре) и не трогай даже! ну,
если тронешь - ну, сходи руки помой

Тут есть один перенос, подпавший под правило №1 (слово "извиняюсь") , и он выполнен. Если задать длину строки 39, то переноса получается аж два! Тут, конечно, есть ошибки, если заметишь - скажи. Это же еще не релиз.. smile.gif
А что она выдает тебе?.. blink.gif

> А можно попроще для меня сказать еще раз?
Фу, я в своем репертуаре... каким-то образом выпустил главное.. извинишь? smile.gif Вот как надо:
  VowDOS:srting='АаЕеЁёИиОоУуЫыЭэЮюЯя';
ConDOS:srting='БбВвГгДдЖжЗзКкЛлМмНнПпРрСсТтФфХхЦцЧч';
IShDOS:srting='Йй';
SHzDOS:srting='ЪъЬь';

Давай, плыви дальше smile.gif
Gold_Fish
В общем-то ничего и не выдает smile.gif)) ( может быть я не туда смотрю конечно: надо в сам файл чтоли заглядывать потом? unsure.gif )
Вот смотри что пишет:
Цитата
Program c:\document and setting\fomin\desctop\cool\marinochka.exe
exited with
exitcode = 2

nea.gif
Где тогда результат смотреть??? rolleyes.gif
Цитата
>А можно попроще для меня сказать еще раз?
Фу, я в своем репертуаре... каким-то образом выпустил главное.. извинишь? Вот как надо:


VowDOS:srting='АаЕеЁёИиОоУуЫыЭэЮюЯя';
ConDOS:srting='БбВвГгДдЖжЗзКкЛлМмНнПпРрСсТтФфХхЦцЧч';
IShDOS:srting='Йй';
SHzDOS:srting='ЪъЬь';

Спасибки give_rose.gif
Lapp
> В общем-то ничего и не выдает smile.gif))
> ...
> Вот смотри что пишет:
> exitcode = 2
И это нынче называется "ничего не выдает"?.. Подруга подводоплавающая, это как раз и есть самая главная выдача! И значит она, что файл не найден.. Ты какой файл вводишь по запросу? мы, кажется, договорились на имена d.txt и w.txt. Пока прога работает только с досовской кодировкой, так что давай ей d.txt. И он должен быть в этой директории.. Ясно? smile.gif
Gold_Fish
Теперь вообще FPC другую штуку пишет (типа ошибки, наверное, в новом окошке внизу) unsure.gif
А TP выдает ошибку №3 перед типом String, в штуке которую мы изменили.
nea.gif

Цитата(Lapp @ 11.12.2006 14:01) *

> В общем-то ничего и не выдает smile.gif))
> ...
> Вот смотри что пишет:
> exitcode = 2
И это нынче называется "ничего не выдает"?.. Подруга подводоплавающая, это как раз и есть самая главная выдача! И значит она, что файл не найден.. Ты какой файл вводишь по запросу? мы, кажется, договорились на имена d.txt и w.txt. Пока прога работает только с досовской кодировкой, так что давай ей d.txt. И он должен быть в этой директории.. Ясно? smile.gif

Ну я вводила d.txt точно smile.gif))
Алена
Цитата
А TP выдает ошибку №3 перед типом String, в штуке которую мы изменили.


sTRing попробуй набрать, вместо того, что сейчас ...
Lapp
Цитата(Алена @ 11.12.2006 15:06) *

sTRing попробуй набрать, вместо того, что сейчас ...

Спасибо, Алена smile.gif
Gold_Fish, еще раз извини.. sad.gif
Gold_Fish
УРА!!! Заработало lol.gif
Там просто вместо string было srting написано, а я не проверила ...
Воть, честенько я невнимательностью страдаю к сожалению wacko.gif
Спасибки Алена smile.gif
Lapp, хватит уже извиняться-то smile.gif)) если бы не ты мне бы ноль в скором будущем поставили наверное smile.gif Поэтому спасибки большое give_rose.gif
Lapp
Цитата(Gold_Fish @ 11.12.2006 15:04) *

Ну я вводила d.txt точно smile.gif))

Против сверхъестественных явлений я пас.. Ошибка однозначная - файл не найден. Ищи.
Gold_Fish
Цитата(Lapp @ 11.12.2006 14:13) *

Против сверхъестественных явлений я пас.. Ошибка однозначная - файл не найден. Ищи.

Теперь уже TP работает smile.gif , а FPC прежнюю штучку пишет unsure.gif
Lapp
Цитата(Gold_Fish @ 11.12.2006 15:15) *

Теперь уже TP работает smile.gif , а FPC прежнюю штучку пишет unsure.gif

Что ТР работает - это хорошо, но хотелось бы узнать, что за штучка.. Она при компиляции или при работе? Если при компиляции, то пойди в Options - Compiler - Code Generation и проставь там Turbo Pascal Compatible. И вообще, постарайся быть поконкретнее в сообщениях об ошибках.. иначе мы уйму времени потратим впустую.

В любом случае можешь продолжать в ТР. Вернись к мессаджу 21 и продолжай в духе того, что там написано.
Gold_Fish
Цитата(Lapp @ 11.12.2006 14:26) *

Что ТР работает - это хорошо, но хотелось бы узнать, что за штучка.. Она при компиляции или при работе? Если при компиляции, то пойди в Options - Compiler - Code Generation и проставь там Turbo Pascal Compatible. И вообще, постарайся быть поконкретнее в сообщениях об ошибках.. иначе мы уйму времени потратим впустую.

В любом случае можешь продолжать в ТР. Вернись к мессаджу 21 и продолжай в духе того, что там написано.


Штучку прежнюю, где
Цитата
exited with
exitcode = 2

написано. unsure.gif
Попробую продолжить в духе мессаджа #21 smile.gif Не думаю, конечно, что получится, но надо попробовать rolleyes.gif
Lapp
> Штучку прежнюю, где
> exited with
> exitcode = 2
> написано. unsure.gif
Файл лежит в той же директории и не читается?.. чудеса..


> Попробую продолжить в духе мессаджа #21 smile.gif
> Не думаю, конечно, что получится, но надо попробовать rolleyes.gif
Обязательно надо smile.gif. Кроме шуток smile.gif

Заметил еще одну квазиошибку в том своем тексте..
Закомментируй, плз, строчки:
  Assign(fOu,'tst-ou-w.txt');
ReWrite(fOu);

Ну, давай. Девиз всех Рыбок: плавать в море, чтоб не плавать на зачете! smile.gif
Gold_Fish
Цитата(Lapp @ 11.12.2006 14:55) *

Заметил еще одну квазиошибку в том своем тексте..
Закомментируй, плз, строчки:
  Assign(fOu,'tst-ou-w.txt');
ReWrite(fOu);


Что сделать? unsure.gif
> Ну, давай. Девиз всех Рыбок: плавать в море, чтоб не плавать на зачете! smile.gif
Спасибки smile.gif))
Lapp
Цитата(Gold_Fish @ 11.12.2006 16:01) *

Что сделать? unsure.gif

Заключить в фигурные скобки smile.gif))))))))
Gold_Fish
Цитата(Lapp @ 11.12.2006 15:05) *

Заключить в фигурные скобки smile.gif))))))))

Ну не надо смеятся, я же не такая умная как Вы, дорогой друг Lapp, и не знала что это такое rolleyes.gif
Lapp
Цитата(Gold_Fish @ 5.12.2006 21:54) *

2) две идущие подряд согласные можно разделить, если первой из них стоит гласная, ...

Вот это как понимать?.. blink.gif
Michael_Rybak
Наверное "две идущие подряд согласные можно разделить, если перед первой из них стоит гласная, ..."
Gold_Fish
Цитата(Lapp @ 11.12.2006 15:53) *

Вот это как понимать?.. blink.gif

Да, не знаю, так в методичке написано. Наверное слово "перед" пропущено, хотя мб и нет, но тогда странно сказано nea.gif
Lapp
Пишу пояснения к реализации Правила №1 (см. пост №20)
Итак, к этому моменту у нас есть следующее:
- в переменной s лежит текущая строка (без последнего слова);
- в переменной t лежит последнее слово, которое нам как раз и надо разделить на части.

Во-первых, внимательно прочитав Пр.1, мы приходим к выводу, что в нем участвуют по крайней мере 4 буквы (две гласные, одна согласная перед ними и одна любая после них). Следовательно, для работы по Пр.1 нам нужны слова, которые содержат как минимум 4 буквы. Поэтому мы можем поставить условный оператор if, который будет фильтровать для нас все слова, давая только те, которые содержат не менее 4 букв:
if Length(t)>=4 then ...

Все дальнейшее, относящееся к этому правилу, мы заключим в операторные скобки begin-end, чтобы программа пропустила все это, если слово имеет менее 4 букв.
(Замечание: в приведенном расуждении есть ошибка. Не старайся ее найти, это не так просто. Я все исправлю и объясню потом. Сейчас не хочу сбивать тебя с толку исправлениями на ходу).

Это было как бы подготовительное действие, и оно было простым. Сделаем еще одно подготовительное действие, немного более сложное.. Уделим внимание последнему утверждению из Пр.1, к тому же заключенному в скобки. Оно гласит, что буква "й" в определенных ситуациях считается единым целым с предыдущей буквой. Иными словами, комбинацию типа "ай" можно заменить просто буквой "а", то есть выкинуть "й". Проще говоря, буква "й" в некоторых ситуциях лишняя. Выкидываем ее в цикле, отыскивая означенные комбинации. Но выкидывание буквы "й" повредит самому тексту, который станет после этого содержать ошибки! Значит, сначала делаем копию слова (в переменной w), и уже над ней производим описанную операцию:

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;

Если ты сравнишь приведенные два куска с полным кодом (пост №20), то увидишь, что между ними есть строчка, которой я не уделил внимания. Кроме того, во втором фрагменте есть оператор Delete(Map,i,1) непонятного (пока) назначения... Зачем это? А вот, зачем..

Выидывание буквы "й" не только повредит тексту (о чем я упомянул раньше, и от чего мы типа защитились копированием), но еще и изменит нумерацию в слове! То есть, если в слове "койот" буквы "о" и "т" имеют номера 4 и 5 соответственно, то после выкидывания (в соответствии с Пр.1) буквы "й" мы получим слово "коот", в котором упомянутые буквы имеют номера 3 и 4. Это может сыграть с нами злую шутку, когда мы станем делить слово на части (ведь делить надо оригинальное слово, а не его копию, лишенную "й"), так как мы запутаемся в нумерации букв, копируемых в две разные части. Чтобы это не случилось, мы делаем карту нашего слова, нумеруя все буквы по порядку (именно это и делает пропущенная строка). Когда же мы выбрасываем "й", мы выбрасываем и его номер. Например, изначально карта слова "койот" была 12345, а после выбрасывания "й" она стала 1245. Эту информацию мы используем в дальнейшем при разбиении слова..

Следующий цикл - собственно реализация Пр.1. Мы проходим циклом с конца слова (с предпоследней буквы - почему?) до начала (до второй буквы - почему?), пытаясь выявить комбинации, подпадающие под Пр.1. Рассмотри внимательно условие, и ты узришь в нем то самое правило: если вторая буква (с конца) гласная, и третья гласная, а четвертая согласная, а первая (то есть самая правая) есть буква (а не точка, не запятая и т.п.), то слово можно разделить между двумя гласными, то есть между буквой с номером i и буквой с номером i+1.

Заметим, что эта нумерация - нумерация в слове с выкинутыми "й", то есть неправильная нумерация для оригинального слова. Вот тут-то мы и вспоминаем про запасенную карту слова.. В результате к имеющейся строке s дописывается кусок орининального слова t длиной, равной номеру i-го символа в оригинальном слове. И точно такая же часть удаляется из t, которое будет содержать остаток слова, который в свою очередь явится началом новой строки..

Мораль: жизнь бесконечно многообразна, что есть, впрочем, флуд smile.gif.
Рыбка, я тебя очень прошу, уважь плод труда моего ночного бдения, прочти все внимательно (желательно не единожды) и постарайся разобраться. Это в твоих силах.. и интересах smile.gif

И после этого, на базе, так сказать, приобретенных знаний smile.gif, попробуй еще раз воплотить Пр.2. Извини, но первый твой подход к этой штанге был неуспешным.. Думаю, ты это и сама поняла - либо растолкуй мне еще раз.

Последнее: в дальнейшем никаких исключений - по вопросам Форума я в личке не отвечаю. И даже не читаю.
Gold_Fish
Ура!!! Заработало, у меня перенеслось слово «выб-роси» из тех заумных мыслей мессаджа №17 с помощью второго правила, только там мягких и твердых знаков нету … smile.gif)) (Но, я когда там мягкий знак приписывала все получалось) rolleyes.gif
Вот программа, только, наверное, в ней надо что-то поменять, а то повторяется несколько строчек в конце:

{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.

smile.gif))
Gold_Fish
Подскажите пожалуйста, как задать момент, когда вторая часть слова содержит хотя бы одну гласную??? nea.gif
Lapp
> Ура!!! Заработало,
Правда приятно, когда сам что-нить сделаешь и.. работает!! smile.gif Ни с чем несравнимое чувство..

> у меня перенеслось слово «выб-роси»
Да, видел. Congratulations! good.gif
Но, к сожалению, из этой фразы я делаю вывод, что ты не пыталась менять значение константы Lx. Меняя ее, ты можешь регулировать длину строки и прогонять снова, получая много маленьких радостей.. smile.gif Или огорчений, если обнаружатся ошибки.. Ошибки есть всегда, увы - это закон. Вот, например:

> только там мягких и твердых знаков нету … smile.gif))
> (Но, я когда там мягкий знак приписывала все получалось)
- это странно. В обработке карты Map у меня была ошибка (сейчас исправлено), в результате нее мягкий знак переносился на следующую строчку, что, ессно, неправильно.

Но все же, ты молодец. В целом ты произвела правильные действия, хотя и не все..
Во-первых, нужно было взять больший кусок, включая копирование t в w (как же иначе? мы же испортили w, когда обработали его первым правилом).
Во-вторых, нужно было организовать выбор из результатов, полученных по Пр.1 и Пр.2. Не применять их сразу очертя голову, а выяснить, какой из двух предлагаемых переносов лучше (если слово допускает оба переноса, и 1, и 2 типа). Я ввел соответствующий механизм, основанный на массиве Cuts размера 3 (по числу правил), который содержит длины первой части слова (оставляемой на старой строке). Короче, ошибки были, но я доволен тем, что ты сделала smile.gif. Респект!

Тепрь дальше по делу.
В первую очередь - мой должок. Я говорил о том, что в алгоритме Пр.1 есть ошибка. Исправляю ее.
Дело в том, что проверка на минимальную длину слова должна стоять после выбрасывания Й (или мягких и твердых знаков в Пр.2). Иначе после выбрасывания длина слова может сократиться до 3 букв, что приведет к ошибкам. Сейчас это исправлено (посмотри, сравни новый и старый коды).

Кроме этого, я нашел и исправил еще пару ошибок (не пугайся, у себя smile.gif). О первой я уже сказал в самом начале (посмотри и найди отличия в операторе IF после проверки правила, обоих из них). А вторая ошибка состояла в том, что я не прекращал разбор слова после того, как разрез, подходящий по длине, был уже найден. Это приводило к тому, что при нахождении еще одного разреза перенос получался более короткий. Я исправил это вставлением оператора Break, который прекращает выполнение цикла (найди оба места места, где стоит Break и разбери подробно).

Еще одно исправление. Хотя это не ошибка, но все же было некрасиво. Карта Map у меня была раньше строкой, хотя я использовал ее для хранения чисел. Сейчас я сделал ее обычным массивом. Это привело, например, к невозможности использования процедуры Delete с ней, но это особо и не нужно (заменил циклом, посмотри).

> Подскажите пожалуйста, как задать момент, когда
> вторая часть слова содержит хотя бы одну гласную???
Замечательный вопрос, он показывает, что уровень твоего понимания достаточно высокий smile.gif. Нет, в самом деле - прогресс налицо! smile.gif
Подсказываю. Я завел некий флаг (булева переменная Flag, найди ее в определении переменных), которой снячала присваиваю значений false (ложь), то есть флаг сброшен. В цикле перебора букв слова я присваиваю ей саму себя ИЛИ результат проверки буквы на гласность. То есть она будет оставаться false до тех пор, пока все буквы согласные (оба параметра ложные), но при первой гласной ей присвоится значение true (правда), и оно уже не сбросится, потому что первый операнд (то есть она сама) операции OR всегда будет с этих пор true. То есть флажок как бы встает при встрече гласной и больше не падает. После этого я использую Flag в логическом выражении для Пр.2. Разбери все это внимательно и убедись, что поняла - или задавай вопросы..

Давай - изучай, разбирайся - и продвигайся дальше! Правило 3 на очереди.. smile.gif
Успеха!

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.
Gold_Fish
Спасибки give_rose.gif
Цитата
>Но, к сожалению, из этой фразы я делаю вывод, что ты не пыталась менять значение константы Lx

Еще как пыталась smile.gif , я и текст другой пробовала создавать вот в нем и пыталась, только вот там (после переноса) вообще слова не печатались Паскалем no1.gif
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


Во как, а скорее всего немного не так smile.gif
Цитата
>Мне кажется, удобно было бы устроить запрос длины строки (Lx) от пользователя. Сможешь сделать?

Смотри (и не учись, ты же умеешь smile.gif)) :
Итак, для того чтобы пользователь сам задавал желаемую длину строки необходимо написать вот что:
Цитата
Write(‘Введите желаемую длину строки: Lx=’);
Read(Lx);

При этом необходимо в начале программы при перечислении переменных задать переменную Lx целого типа (integer), так как длина строки (то есть количество символов в строке) обязательно целая! (Ну я и сказанула … smile.gif) )
Кстати я в начале так и думала, что Lx наверное должен пользователь задавать smile.gif
Ну так что же мне писать там в 3 правиле, в том месте где я нинаю rolleyes.gif
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;

- что ты хотела сказать вот этим:
((w[i-1] in Con) or (w[i-1] in Vow))
? Что w[i-1] должна быть буквой? Если да, то лучше использовать не два множеста (гласные и согласные), а одно специальное множество Let, которое содержит все буквы (не только гласные и согласные, но и Ъ с Ь, а также Й). Посмотри, как оно заполняется, и все поймешь.

> Во как, а скорее всего немного не так smile.gif
Я бы сказал, почти совсем не так. Похоже, для меня настало время небольшого (надеюсь) разочарования.. sad.gif В предыдущем моем мессадже был подробно объяснен твой нынешний вопрос. Но ты почему-то не только совсем не учитываешь этого, но и вообще строишь свои рассуждения на основе старого кода, от которого мы уже ушли, и тащишь за собой старые ошибки, уже исправленные мной... Подсаживаешь их, как клопиков из старого дивана, любовно собранных в коробочку, в новый диван. Ты совсем-совсем ничего не вынесла из последней моей, гм.. лекции?.. Проболтала всю пару с соседом?.. Ну что ж, теперь я поболтаю.. с соседкой.. dry.gif А ты все же потрудись разобраться! И не пытайся ссылаться на трудное детство, скользкий подоконник, бому в коляске.. Я-то знаю, на что ты способна..

> Итак, для того чтобы пользователь сам задавал желаемую длину строки
> необходимо написать вот что:
Да, тут правильно yes2.gif . Хотя, я бы использовал ReadLn, а не Read. Но это вопрос вкуса. Осталалось вставить это вс программу.

Ну, я пошел болтать..
Кстати, что у нас на обед?.. О, рыба! Положите мне вот эту.. Да-да, золотую.. Загрызу с удовольствиеммм!!
smile.gif
Gold_Fish
Цитата(Lapp @ 14.12.2006 4:29) *

А ты все же потрудись разобраться!

Я не понимаю как переделать, подскажите пожалуйста mega_chok.gif
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.