Помогите, пожалуйста, очень прошу, хотя бы частично: Перенос слова. Перенос русского слова с одной строки на другую с большей вероятностью выполняется правильно, если пользоваться следующими правилами: 1)две идущие подряд гласные можно разделить, если перед первой из них стоит согласная, а за второй идет хотя бы одна буква (буква й при этом рассматривается вместе с предшествующей ей гласной как единое целое); 2) две идущие подряд согласные можно разделить, если первой из них стоит гласная, а в той части слова, которая идет за второй согласной, имеется хотя бы одна гласная (буквы ь, ъ вместе с предшествующей согласной рассматриваются как единое целое); 3) если не удается применить первые два правила, то слово разбивают так, чтобы первая часть содержала более чем одну букву и оканчивалась на гласную, а вторая содержала хотя бы одну гласную. Дан текст, состоящий из нескольких строк. Преобразовать текст таким образом, чтобы длина строк не превышала заданного значения, используя при этом перенос слов.
Как найти ближайший к концу строки пробел, если при заданном значении слово "как бы разбивается"? Как осуществить на Паскале приведенный выше перенос???
Lapp
6.12.2006 11:13
Цитата(Gold_Fish @ 5.12.2006 21:54)
Дан текст, состоящий из нескольких строк. Преобразовать текст таким образом, чтобы длина строк не превышала заданного значения, используя при этом перенос слов.
Как найти ближайший к концу строки пробел, если при заданном значении слово "как бы разбивается"? Как осуществить на Паскале приведенный выше перенос???
Первый и главный вопрос к тебе: знаки препинания не нужно учитывать? Это ведь тоже непростой вопрос. Например, обычно их нельзя переносить (отрывать от слова). А тире, скажем, отделяется от слова пробелом, но переносить его при этом тоже не стОит. Есть многосимвольные знаки препинания (... , ?.. , !.. , ..). И нужно ли сохранять пробелы в конце строки (впрочем, это, наверное, нет). Еще, есть такой особый знак препинания, как "красная строка", например.. Короче, ответь.
Второй вопрос.. Не совсем понятен пункт 1. Правильно я понимаю, что в соответствии с ним слова "параноик", "наитие", "кондуит" нельзя перенести так: парано-ик, на-итие, конду-ит?
Если пока забыть про знаки препинания и остальные проблемы, то начать можно примерно так.. От начала текста отмеряем максимальную длину строки (Lx) и смотрим, попадает ли разрыв в тело слова. Признаком этого можно считать наличие букв (а не пробелов, знаков препинания..) по обе стороны от разрыва. Вот я тут набросал примерный текст программки, которая берет в отдельную строку s слово, попавшее на разрыв. Дальше можно с ним развлекаться и смотреть, как его можно делить. Моя программа делает это пока только по урезанному первому правилу для, так сказать, демонстрации . Если прояснятся вышеупомянутые вопросы, могу поучаствовать и в дальнейшем развитии проги. Задачка интересная . Интересно, где такие задают?
{ 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
6.12.2006 18:48
Ой, неужели кто-то мне помог!!! Спасибо Iapp огромное, преогромное!!! Насчет пункта №1: извиняюсь, не так немножко, там буква й при этом рассматривается вместе с предшествующей ей гласной как единое целое (я полагаю, что если перед й стоит гласная, то они рассматриваются как единое целое). А вот, про знаки препинания не знаю, так как в задаче ничего не сказано. Задают такие задачи в Ивановском Государственном Энергетическом Университете на 1 курсе, факультета ИВТФ. Помогите доделать, пожалуйста.
Lapp
6.12.2006 19:12
Цитата(Gold_Fish @ 6.12.2006 15:48)
Помогите доделать, пожалуйста.
Помочь - не проблема . Но ты сначала разберись в том, что есть, и покажи, что разобралась. Твой ход.
Значит, в Энергетическом.. Хм, забавно. Я все же думал, что что-то более близкое к гуманитарной области. Но все равно приятно такое видеть - особенно на фоне повального "удаффа" и не только. А уж про перенос стали забывать даже в книгопечатаньи..
и - Lapp я.. Лопарь.
Gold_Fish
6.12.2006 21:07
Я знаю, что 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.
А как же мне сделать, чтобы остальные слова и часть перенесенного слова печатались на новой строке???
Lapp
7.12.2006 11:30
Цитата(Gold_Fish @ 6.12.2006 18:07)
Ну так вот, ввожу я уже свой текст:
Хорошо, что вводишь. Но только.. 1. Почему в программе исчезло все форматирование? Я имею в виду сдвиги. У меня все было аккуратно. Учти, это очень важно. И еще учти, что я не хочу тратить вреям на восстановление форматирования вручную каждый раз! Будь добра, сохраняй его, а также сама старайся писать правильно.. 2. Когда постишь прогу, используй теги Паскаля (выбери в выпадающем меню со словом CODE над окном ввода). Опять же, я постоянно исправлять не намерен (это я уже как админ тебе говорю).
Цитата(Gold_Fish @ 6.12.2006 18:07)
А как же мне сделать, чтобы остальные слова и часть перенесенного слова печатались на новой строке???
Не спеши.. Все будет.. Как я уже говорил, та программа была нацелена не на решение поставленной задачи, а на демонстрацию методов. Теперь, когда все более-менее прояснилось, можно начать систематически решать проблему.. Для этого начнем все заново. Ты готова? Шаг за шагом разберемся во всем и подойдем к решению. По пути задавай вопросы, если что непонятно. Если сразу все ясно - пиши свой вариант Согласна с таким подходом? Пока считаю, что Да, согласна (но ты все же ответь), и начинаю продолжать .
Сначала разберемся с вводом текста. Думаю, ввод надо осуществлять из файла. Причем, поскольку в нормальном обычном тексте длина строки может быть больше 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 написано, вот и исправила
нет, там было маленькое L (l). Сейчас я исправил на большое..
Gold_Fish
8.12.2006 1:49
Спасибки, Lapp Почти все дошло, кроме: почему пишет что begin не хватает в:
Цитата
Vowels_Win:set of char= ['А','а','Е','е','Ё','ё','И','и','О','о','У','у','Ы','ы','Э','э','Ю','ю','Я','я']; Vowels_DOS:set of char= ['_',' ',':','_','р','с','_','Ё','_','R','"','г','>','л','_','н','_','о','_','п'];
и почему то на русский алфавит мой Паскаль не переходит, хотя у него и справка русская. Да, и если поставить Begin, то выдает потом ошибку №3. Еще не оч поняла смысл этой аброкадабры, вернее её перевод:
Цитата
Write(''ў_¤Ёв_ Ё┐п д c< ¤<п дRа┐ вЁаRў -Ёп: ');
И в [#$0D,#$0A] выдает тоже ошибку, почему? и что такое EoF? tst-ou-w.txt - это я так понимаю имя файла, а мне его заранее создать придется?
Цитата
Для копирования файлов и текстов очень рекомендую использовать программку Far. Знакома ты с ней? Ответь, пожалуйста.
Нет
Цитата
Постарайся, чтоб при копировании русские буквы не превратились в белиберду. Обязательно скажи, удалось ли тебе это.
Никак у меня с русскими не получается, он не хочет почему-то переключаться на русский текст... А так суть остального и предназначения я поняла Ой сколько я много вопросов накатала, извиняюсь, но так вышло Ответьте пожалуйста, заранее спасибо
Lapp
8.12.2006 8:28
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.
Pola
8.12.2006 15:16
Цитата(Gold_Fish @ 7.12.2006 21:49)
Спасибки, Lapp Почти все дошло, кроме: почему пишет что begin не хватает в:
Может const не скопировала?
Gold_Fish
8.12.2006 19:45
Из браузера я не копирую, а сама перепечатываю в Паскаль, мне так разобраться легче
Цитата
Ну, давай, успехов тебе..
Спасибки, сейчас буду разбираться Ах, да, я на своем компе работаю И ещё:
Цитата
И чтобы правильно копировать файлы, я настоятельно рекомендую тебе установить Far. Я тебя спрашивал о нем раньше, но ты деликатно промолчала.
Я писала, что не знакома с этой прогой Я вспомнила у меня папа всегда ей пользуется, но она у него какая-то древняя , поэтому я её не открываю
Цитата(Pola @ 8.12.2006 11:16)
Может const не скопировала?
Не, я писала const
Lapp
8.12.2006 19:55
Цитата(Gold_Fish @ 8.12.2006 16:45)
Из браузера я не копирую, а сама перепечатываю в Паскаль, мне так разобраться легче ... Я вспомнила у меня папа всегда ей пользуется,
Сама перепечатываешь - это хорошо, но внимание удвой, как минимум.. Одна точка вместо запятой - и все в тартарары.. Отлично! вот папа будет рад, что ты у него будешь консультироваться.. ) Она выглядит как старый добрый Нортон, потому и кажется древней. Но она внутри молодая! ))))
Gold_Fish
8.12.2006 20:18
Я установила новый, т к в старом Windows-1251.reg не было, надеюсь мне папа ничего не сделает )) , а что дальше? Насчет внимательности, это да, стараюсь внимательно делать
Gold_Fish
8.12.2006 20:34
Страничка freepascal.org не хочет открываться
Lapp
9.12.2006 9:18
Цитата(Gold_Fish @ 8.12.2006 17:18)
Я установила новый, т к в старом Windows-1251.reg не было, надеюсь мне папа ничего не сделает )) , а что дальше? Насчет внимательности, это да, стараюсь внимательно делать
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, если скачаешь). Проверь, сохранились ли русские буквы и рапортуй
Цитата(Gold_Fish @ 8.12.2006 17:34)
Страничка freepascal.org не хочет открываться
Это жесть.. А ты правда готова качать 28 мег?.. Какой у тя коннекшн? На диалапе при всех самых благоприятных обстоятельствах (что бывает редко) это займет не меньше полутора часов.. Но оно того стОит! Вот прямой линк на файл на русском зеркале: ftp://ftp.chg.ru/pub/lang/pascal/fpc/dist....i386-win32.exe - надеюсь, он сработает.. Ну, давай..
Gold_Fish
9.12.2006 16:22
Цитата(Lapp @ 9.12.2006 5:18)
А ты правда готова качать 28 мег?.. Какой у тя коннекшн? На диалапе при всех самых благоприятных обстоятельствах (что бывает редко) это займет не меньше полутора часов.. Но оно того стОит! Вот прямой линк на файл на русском зеркале: ftp://ftp.chg.ru/pub/lang/pascal/fpc/dist....i386-win32.exe - надеюсь, он сработает.. Ну, давай..
Вот, если чесно мне уже все равно как долго его качать, лишь бы сделать задачу быстрее, сдавать надо, а у меня не сделано
Gold_Fish
9.12.2006 16:52
Премногоуважаемый Lapp! )) Я создала обычный вордовский файл, там написала текст, и все )) И все равно не так, что делать?
Lapp
9.12.2006 17:20
Цитата(Gold_Fish @ 9.12.2006 13:52)
Премногоуважаемый Lapp! )) Я создала обычный вордовский файл, там написала текст, и все )) И все равно не так, что делать?
Милейшая исполнительница желаний безумных старух, Вы создали, извиняюсь-с - doc-файл?.. Дружок, пойди в неказистый синенький Фар, создай там в рабочей твоей директории новый файл - назови, скажем, d.txt. Убедись, однако, что кодировка состоит DOS и сокопируй туда вот этот самовый бред.. сорри, вот эти мои заумные мысли - да, да, прямо отсюда. Да и сохрани его, да и закрой степенно.. Затем, нимало не отдыхаша, открой на редактирование еще один новый файл - и нареки имя ему w.txt. Закокококо.. кхм-кхм.. закопируй туда то же самое, но только в этот раз да вразумит тебя святой Пингвин, покровитель всех программеров, соблюсти кодировку при значении Win (рубильник F8 на твоем распределительном щитке) - да установи оное значение ДО копирования, противу сказать опосля.. И етути двое фалОв да будут отныне для тя тестовыми, ако в транслейшне - попробовательными.. А о сатнинском Word'е - и думать забудь, и трогать его не смей, и выброси его в геенну огненную, и - самое главное - НИКОГДА НЕ смотри в нутро поганое файла того, что создала ты в нем (переключатель F3 (просмотр файла в Фаре) и не трогай даже! ну, если тронешь - ну, сходи руки помой ) O'kay???..
Gold_Fish
9.12.2006 17:50
Здраствуйте, друг мой Lapp! )) (Снова Вас тревожит исполнительница желаний безумных старух) )) Все я сделала как Вы указали, будьте так любезны, скажите, что дальше нужно делать?
Lapp
9.12.2006 19:18
Вот вариант, читающий файл и выдающий отдельно строки (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
10.12.2006 14:22
Более или менее все понятно, а вот куда впихнуть буквы "й, ь, ъ" для них просто массив создать в начале, да? P. S. Дальше не могу продвинуться, никак не составлю условие для переноса Програмка прикольно работает, так интересно переносит твои, как ты выразился
Цитата
вот эти мои заумные мысли
Lapp
10.12.2006 21:31
Вот, есть первый ощутимый результат . Я реализовал первое правило. Получается не так просто, чтобы объяснить в двух словах. Давай, лучше ты посмотришь и станешь задавать вопросы - по сделанному, а не "как дальше".. Я немного подозреваю, что ты смотришь на сделанное, как на пройденный этап, к которому нет смысла возвроащаться.. А это неправильно, так как именно в этом и состоит твой прогресс. Если можешь, развей мои подозрения .
В принципе, реализация остальных правил может быть проведена по образу и подобию первого. Так что если ты действительно разберешься, ты сможешь это сделать. Извини за отстутствие комментариев, могу добавить позже..
> Более или менее все понятно, а вот куда впихнуть буквы "й, ь, ъ" > для них просто массив создать в начале, да? Я вообще несколько переделал организацию ввода алфавита. Ну, увидишь, как. Это для простоты, компактности и лучшей читаемости (да и писаемости тоже ) кода, особенно когда несколько кодировок.
> 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 }
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
10.12.2006 23:41
Цитата
Я немного подозреваю, что ты смотришь на сделанное, как на пройденный этап, к которому нет смысла возвроащаться.. А это неправильно, так как именно в этом и состоит твой прогресс. Если можешь, развей мои подозрения
Сейчас разберусь в проге и попробую развеять )) И спасибо Сударь, благодаря Вам я плавно приближаюсь к окончанию первого семестра моего учения, благодаря Вашей бескорыстной помощи
Gold_Fish
11.12.2006 0:50
Что-то не очень понимаю вот это место:
Цитата
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 Что тогда значит "i" ? Ещё вот это можно пояснить:
Цитата
s:=s+Copy(t,1,Ord(Map[i]))+'-';
Что такое тут Copy(t,1,Ord(Map[i])) ?
Lapp
11.12.2006 5:52
> И почему-то перед [i] ошибка №121 TP этого действительно не пропускает. Я думал, что ты уже перешла на FPC.. Для того, чтобы это скомпилить в TP, добавь тип string в определение конмтант, вот так:
> Что-то не очень понимаю вот это место: > for i:=1 to Length(VowDOS) do Include(Vow,VowDOS[i]); > ... Это заполнение множеств. Раньше я задавал их непосредственно (см. старый вариант проги), а сейчас через строчку-константу. Так удобнее, согласись. Правда, требует лишних операторов (вот этих).
> Что такое тут Copy(t,1,Ord(Map[i])) ? Копирование части строки. В указанном документе см. Приложение 4, Модуль System, П 4.1.3.
Давай, Рыбка - барахтайся, а то утонешь!
Gold_Fish
11.12.2006 12:37
Барахтаюсь В FPC я тоже пробовала эту прогу, да он пропускает это место, но в результате непонятно что мне выдает, вот так
Цитата
Для того, чтобы это скомпилить в TP, добавь тип string в определение конмтант
А можно попроще для меня сказать еще раз?
Lapp
11.12.2006 15:06
> В 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, то переноса получается аж два! Тут, конечно, есть ошибки, если заметишь - скажи. Это же еще не релиз.. А что она выдает тебе?..
> А можно попроще для меня сказать еще раз? Фу, я в своем репертуаре... каким-то образом выпустил главное.. извинишь? Вот как надо:
> В общем-то ничего и не выдает )) > ... > Вот смотри что пишет: > exitcode = 2 И это нынче называется "ничего не выдает"?.. Подруга подводоплавающая, это как раз и есть самая главная выдача! И значит она, что файл не найден.. Ты какой файл вводишь по запросу? мы, кажется, договорились на имена d.txt и w.txt. Пока прога работает только с досовской кодировкой, так что давай ей d.txt. И он должен быть в этой директории.. Ясно?
Gold_Fish
11.12.2006 18:04
Теперь вообще FPC другую штуку пишет (типа ошибки, наверное, в новом окошке внизу) А TP выдает ошибку №3 перед типом String, в штуке которую мы изменили.
Цитата(Lapp @ 11.12.2006 14:01)
> В общем-то ничего и не выдает )) > ... > Вот смотри что пишет: > exitcode = 2 И это нынче называется "ничего не выдает"?.. Подруга подводоплавающая, это как раз и есть самая главная выдача! И значит она, что файл не найден.. Ты какой файл вводишь по запросу? мы, кажется, договорились на имена d.txt и w.txt. Пока прога работает только с досовской кодировкой, так что давай ей d.txt. И он должен быть в этой директории.. Ясно?
Ну я вводила d.txt точно ))
Алена
11.12.2006 18:06
Цитата
А TP выдает ошибку №3 перед типом String, в штуке которую мы изменили.
sTRing попробуй набрать, вместо того, что сейчас ...
Lapp
11.12.2006 18:10
Цитата(Алена @ 11.12.2006 15:06)
sTRing попробуй набрать, вместо того, что сейчас ...
Спасибо, Алена Gold_Fish, еще раз извини..
Gold_Fish
11.12.2006 18:10
УРА!!! Заработало Там просто вместо string было srting написано, а я не проверила ... Воть, честенько я невнимательностью страдаю к сожалению Спасибки Алена Lapp, хватит уже извиняться-то )) если бы не ты мне бы ноль в скором будущем поставили наверное Поэтому спасибки большое
Lapp
11.12.2006 18:13
Цитата(Gold_Fish @ 11.12.2006 15:04)
Ну я вводила d.txt точно ))
Против сверхъестественных явлений я пас.. Ошибка однозначная - файл не найден. Ищи.
Gold_Fish
11.12.2006 18:15
Цитата(Lapp @ 11.12.2006 14:13)
Против сверхъестественных явлений я пас.. Ошибка однозначная - файл не найден. Ищи.
Теперь уже TP работает , а FPC прежнюю штучку пишет
Lapp
11.12.2006 18:26
Цитата(Gold_Fish @ 11.12.2006 15:15)
Теперь уже TP работает , а FPC прежнюю штучку пишет
Что ТР работает - это хорошо, но хотелось бы узнать, что за штучка.. Она при компиляции или при работе? Если при компиляции, то пойди в Options - Compiler - Code Generation и проставь там Turbo Pascal Compatible. И вообще, постарайся быть поконкретнее в сообщениях об ошибках.. иначе мы уйму времени потратим впустую.
В любом случае можешь продолжать в ТР. Вернись к мессаджу 21 и продолжай в духе того, что там написано.
Gold_Fish
11.12.2006 18:37
Цитата(Lapp @ 11.12.2006 14:26)
Что ТР работает - это хорошо, но хотелось бы узнать, что за штучка.. Она при компиляции или при работе? Если при компиляции, то пойди в Options - Compiler - Code Generation и проставь там Turbo Pascal Compatible. И вообще, постарайся быть поконкретнее в сообщениях об ошибках.. иначе мы уйму времени потратим впустую.
В любом случае можешь продолжать в ТР. Вернись к мессаджу 21 и продолжай в духе того, что там написано.
Штучку прежнюю, где
Цитата
exited with exitcode = 2
написано. Попробую продолжить в духе мессаджа #21 Не думаю, конечно, что получится, но надо попробовать
Lapp
11.12.2006 18:55
> Штучку прежнюю, где > exited with > exitcode = 2 > написано. Файл лежит в той же директории и не читается?.. чудеса..
> Попробую продолжить в духе мессаджа #21 > Не думаю, конечно, что получится, но надо попробовать Обязательно надо . Кроме шуток
Заметил еще одну квазиошибку в том своем тексте.. Закомментируй, плз, строчки:
Assign(fOu,'tst-ou-w.txt'); ReWrite(fOu);
Ну, давай. Девиз всех Рыбок: плавать в море, чтоб не плавать на зачете!
Gold_Fish
11.12.2006 19:01
Цитата(Lapp @ 11.12.2006 14:55)
Заметил еще одну квазиошибку в том своем тексте.. Закомментируй, плз, строчки:
Assign(fOu,'tst-ou-w.txt'); ReWrite(fOu);
Что сделать? > Ну, давай. Девиз всех Рыбок: плавать в море, чтоб не плавать на зачете! Спасибки ))
Lapp
11.12.2006 19:05
Цитата(Gold_Fish @ 11.12.2006 16:01)
Что сделать?
Заключить в фигурные скобки ))))))))
Gold_Fish
11.12.2006 19:10
Цитата(Lapp @ 11.12.2006 15:05)
Заключить в фигурные скобки ))))))))
Ну не надо смеятся, я же не такая умная как Вы, дорогой друг Lapp, и не знала что это такое
Lapp
11.12.2006 19:53
Цитата(Gold_Fish @ 5.12.2006 21:54)
2) две идущие подряд согласные можно разделить, если первой из них стоит гласная, ...
Вот это как понимать?..
Michael_Rybak
11.12.2006 19:56
Наверное "две идущие подряд согласные можно разделить, если перед первой из них стоит гласная, ..."
Gold_Fish
11.12.2006 19:57
Цитата(Lapp @ 11.12.2006 15:53)
Вот это как понимать?..
Да, не знаю, так в методичке написано. Наверное слово "перед" пропущено, хотя мб и нет, но тогда странно сказано
Lapp
12.12.2006 20:08
Пишу пояснения к реализации Правила №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, которое будет содержать остаток слова, который в свою очередь явится началом новой строки..
Мораль: жизнь бесконечно многообразна, что есть, впрочем, флуд . Рыбка, я тебя очень прошу, уважь плод труда моего ночного бдения, прочти все внимательно (желательно не единожды) и постарайся разобраться. Это в твоих силах.. и интересах
И после этого, на базе, так сказать, приобретенных знаний , попробуй еще раз воплотить Пр.2. Извини, но первый твой подход к этой штанге был неуспешным.. Думаю, ты это и сама поняла - либо растолкуй мне еще раз.
Последнее: в дальнейшем никаких исключений - по вопросам Форума я в личке не отвечаю. И даже не читаю.
Gold_Fish
12.12.2006 22:04
Ура!!! Заработало, у меня перенеслось слово «выб-роси» из тех заумных мыслей мессаджа №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.
))
Gold_Fish
12.12.2006 23:59
Подскажите пожалуйста, как задать момент, когда вторая часть слова содержит хотя бы одну гласную???
Lapp
13.12.2006 19:36
> Ура!!! Заработало, Правда приятно, когда сам что-нить сделаешь и.. работает!! Ни с чем несравнимое чувство..
> у меня перенеслось слово «выб-роси» Да, видел. 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.
Gold_Fish
13.12.2006 21:22
Спасибки
Цитата
>Но, к сожалению, из этой фразы я делаю вывод, что ты не пыталась менять значение константы Lx
Еще как пыталась , я и текст другой пробовала создавать вот в нем и пыталась, только вот там (после переноса) вообще слова не печатались Паскалем
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
Во как, а скорее всего немного не так
Цитата
>Мне кажется, удобно было бы устроить запрос длины строки (Lx) от пользователя. Сможешь сделать?
Смотри (и не учись, ты же умеешь )) : Итак, для того чтобы пользователь сам задавал желаемую длину строки необходимо написать вот что:
Цитата
Write(‘Введите желаемую длину строки: Lx=’); Read(Lx);
При этом необходимо в начале программы при перечислении переменных задать переменную Lx целого типа (integer), так как длина строки (то есть количество символов в строке) обязательно целая! (Ну я и сказанула … ) ) Кстати я в начале так и думала, что Lx наверное должен пользователь задавать Ну так что же мне писать там в 3 правиле, в том месте где я нинаю
Lapp
14.12.2006 8:29
Вот тут:
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, которое содержит все буквы (не только гласные и согласные, но и Ъ с Ь, а также Й). Посмотри, как оно заполняется, и все поймешь.
> Во как, а скорее всего немного не так Я бы сказал, почти совсем не так. Похоже, для меня настало время небольшого (надеюсь) разочарования.. В предыдущем моем мессадже был подробно объяснен твой нынешний вопрос. Но ты почему-то не только совсем не учитываешь этого, но и вообще строишь свои рассуждения на основе старого кода, от которого мы уже ушли, и тащишь за собой старые ошибки, уже исправленные мной... Подсаживаешь их, как клопиков из старого дивана, любовно собранных в коробочку, в новый диван. Ты совсем-совсем ничего не вынесла из последней моей, гм.. лекции?.. Проболтала всю пару с соседом?.. Ну что ж, теперь я поболтаю.. с соседкой.. А ты все же потрудись разобраться! И не пытайся ссылаться на трудное детство, скользкий подоконник, бому в коляске.. Я-то знаю, на что ты способна..
> Итак, для того чтобы пользователь сам задавал желаемую длину строки > необходимо написать вот что: Да, тут правильно . Хотя, я бы использовал ReadLn, а не Read. Но это вопрос вкуса. Осталалось вставить это вс программу.
Ну, я пошел болтать.. Кстати, что у нас на обед?.. О, рыба! Положите мне вот эту.. Да-да, золотую.. Загрызу с удовольствиеммм!!
Gold_Fish
16.12.2006 2:27
Цитата(Lapp @ 14.12.2006 4:29)
А ты все же потрудись разобраться!
Я не понимаю как переделать, подскажите пожалуйста
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.