Смекни!
smekni.com

Нейминг. Разработка генератора (стр. 2 из 3)

Для разрешения этой ситуации можно составить словарь, содержащий в себе все слова-исключения и их правильные разложения на слоги. Решение это несомненно правильное, но чересчур трудоёмкое и неблагодарное.

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

Поскольку основной целью курсовой работы является всё-таки разработка генератора, то такие недочеты программы можно опустить в связи с их непринципиальностью.

При разработке функции деления слова на слоги, удобно воспользоваться учебником русского языка и основными правилами деления на слоги:

1. Слова делятся на слоги: го-ло-ва, ка-пу-ста(ка-пус-та),<…>, мо-я, я-ма и др.

2. Слог может состоять из одного звука, из двух и более: о-на, у-зел, ко-выль,<…> и др.

3. В состав слога обязательно входит гласный звук, поэтому в слове столько слогов, сколько гласных звуков. <…>

4. Согласные звуки или начинают слог (го-ло-ва), или заканчивают его (он, ум и др.), или окружают гласный звук с обеих сторон (шум, дым и др.)[1].

1.3.2 Алгоритм группировки слогов в слова

Слоги можно группировать по нескольким признакам:

1. по принадлежности к тому или иному ключевому слову, например, не включать в новое слово более n слогов из одного ключевого слова (где n от 1 до количества слогов в слове).

2. по их положению в ключевых словах. Скажем, слоги в новых словах не могут идти в обратном порядке, чем в ключевых; или последние слоги ключевых слов не могут использоваться в качестве первых в новых, и т.д.

3. по повторяемости. Наиболее разумное ограничение – не допускать повторения слога в пределах одного нового слова.

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

Стоит также задуматься о производительности данного алгоритма. Ведь чем больше ключевых слов будет введено, тем больше можно из них создать новых. Стоит учитывать также, что можно формировать слова с количеством слогов от 2-х до n, где n – общее число слогов. Этот фактор также увеличивает количество возможных вариантов.

Поэтому необходимо вводить какие-либо ограничения для выходных данных. Это может быть длина слов, количество слогов в них, степень повторяемости отдельных сочетаний (можно ввести в процентах от длины слова допустимое количество совпадения букв) или что-нибудь в этом роде.

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

2. Реализация алгоритма создания имен

Реализацию полученного алгоритма я решила осуществить на языке PHP 4.0. Свой выбор я обосновываю его синтаксической близостью к языку программирования Си, с которым я наиболее знакома, и простотой работы с данными различных типов (что может особенно пригодиться для создания массивов строк). Кроме того, в процессе работы я смогу улучшить свои навыки работы с PHP, изучить его особенности.

Для ввода входных данных создадим с помощью языка разметки HTMLстраничку, содержащую форму. В её поля должны вводиться:

· количество ключевых слов (поле kol);

· непосредственно слова, записанные через запятую (поле slova);

· количество слогов в генерируемых словах (поле slog).

Данные этой формы будут обрабатываться файлом kurs.php, в результате работы которого будет генерироваться страничка со списком сгенерированных слов.

Сначала необходимо считать данные из формы и записать их в соответствующие переменные.

$kol=$_POST["kol"];

$slova=$_POST["slova"];

$slog=$_POST["slog"];

В переменных kol и slogсейчас находятся какие-либо числа, а в переменной slova находится строка, состоящая из слов, разделенных запятыми и пробелами. Преобразуем её в массив строк (s):

$s=explode(",",$slo);

Для дальнейшей работы нам необходимо еще избавиться от ненужных нам пробельных символов (которые могут появиться при заполнении формы). Для этого воспользуемся встроенной функцией string trim (string str [, string charlist]). После такого рода обработки, можно будет приступить непосредственно к реализации алгоритма разбиения слова на слоги.

2.1 Разработка функции деления слова на слоги

Слова из массива строк sпо одному будем посылать на обработку в функцию delslog($str).

functiondelslog($str)

{$k=k_slog($str); //посчитаем количество слогов

$mas=slog($str, $k); //разобьём слово на слоги

$f=fopen("slogi.txt","a");//откроем файл slogi.txt

for($i=0;$i<count($mas);$i++) //длязаписии

{//через «-» запишем в

$mas[$i].='-'; //него слоги

fwrite( $f,$mas[$i]);}

fclose($f);} //закроем файл

В этой части программы происходит вызов функций k_slog($str)и slog($s, $k). Рассмотрим их подробнее.

functionk_slog($str) //считает количество слогов

{//бежим по строке

for($i=0, $q=0; $i < strlen($str); $i++)

if(glas($str[$i])) // если очередная буква

$q++; //гласная, увеличим счетчик

return $q; } //вернём значение счетчика

Функция slog($s, $k)выполняет непосредственно разбиение слова на слоги. Как видно из примеров в п. 1.3.1, многие слова можно разделить на слоги несколькими способами. По этому определить принадлежность каждой буквы к тому или иному слогу – довольно-таки сложная задача.

Разберемся сначала с гласными буквами. Каждая из них является основой слога, по этому достаточно только отслеживать, чтобы в слог не попала вторая гласная (в этом случае должен осуществиться переход к новому слогу). За это будет отвечать флажок q.

С согласными все сложнее. Из-за разночтений в правилах деления слов на слоги я решила придерживаться следующих пунктов:

1. Согласная и последующая гласная относятся к одному и тому же слогу;

2. Все согласные буквы, находящиеся перед первой гласной принадлежат одному слогу;

3. Все согласные буквы, расположенные после последней гласной принадлежат одному и тому же слогу;

4. Из нескольких согласных, расположенных в середине слова, первая относится к текущему слогу, остальные – к следующему (исключения составляют буквы «ъ» и «ь», которые «привязываются» к предыдущей согласной).

Последний пункт вызывает наибольшее количество сомнений относительно правильности, но вполне удовлетворяет изложенным в учебнике [1] правилам.

Получилифункцию:

function slog($s, $k) //разбиваетсловонаслоги

{for($i=0, $q=0, $j=0; $i<strlen($s);)

{if(glas($s[$i]) && $q==0)//если очередная буква

{ //гласная и первая

$mas[$j].=$s[$i]; //припишем ее к слогу

$q=1; //установим флажок

$i++; //перейдем на след. букву}

else

if(!glas($s[$i]) && ($i==0 || $q!=1 || (glas($s[$i-1]) && !glas($s[$i+1])) || $j==$k-1))

/*если буква не гласная и: первая, или до гласной, или между гласной и согласной, или последняя*/

{

$mas[$j].=$s[$i];//припишем её к слогу

$i++; //перейдем на след. букву}

else

{ $q=0; //иначе снимем флажок и

$j++;} //перейдем на след. слог}

return $mas;} //вернём массив слогов

В приведенных функциях вызывается функция glas($a). Она выглядит так:

functionglas($a) //проверяет, гласная ли буква 'а'

{

$gls='аеёиоуыэюя'; //Запишем строки из строчных и

$glb='АЕЁИОУЫЭЮЯ'; //заглавныхбукв

for($i=0; $i < 11; $i++)

if(substr_count($gls,$a)>0|| //если 'а' входит

substr_count($glb,$a) > 0)//в одну из строк

return 1; // вернём 1

return 0;}

Эта функция ищет вхождение переданной ей буквы a в двух строках, gls и glb, состоящих из строчных и заглавных гласных букв русского алфавита. Она возвращает 1, если буква присутствует в одной из строк (т.е. является гласной), иначе – 0.

Мы получили кусок основной программы, выполняющий первую задачу – разбиение слов на слоги.

В результате работы этой части программы файл slogi.txtзаполняется слогами всех введенных слов, разделёнными знаком «-». Использование файла для временного хранения информации я считаю наиболее выгодным. Этот способ наиболее надежен и прост, потому что в противном случае пришлось бы либо вводить дополнительно переменные под хранение массивов слогов, либо наращивать один массив, но тогда могла бы возникнуть проблема с индексом, т.к. его надо было бы отправлять в качестве ещё одного параметра в функцию delslog($str). Использование нескольких функций вместо одной большой мне кажется также оправданным, т.к. это существенно упрощает восприятие текста программы. К тому же отдельные функции легче исправлять и дополнять.

2.2 Осуществление группировки слогов в слова

После разбиения всех введенных слов на слоги запускается функция группировки слогов в слова (group($k)). У неё только один входной параметр – количество слогов в новых словах.

В основе этой функции лежит алгоритм размещения с повторениями чисел 1..n в последовательности по kэлементов.[5]

Рассмотрим эту функцию.

function group($k)

{

$f=fopen("slogi.txt","rt");//откроемфайл slogi.txt

$a=explode("-",fgets($f));//запишем слоги в масс. а

fclose($f); //закроемфайл

$n=count($a)-1; //посчитаемколичествослогов

for($i=0;$i<$k;$i++){

$x[$i]=1; //зададим начальную и

$y[$i]=$n;} //конечную комбинацию чисел

while(prov($x,$y)) //пока они различны

{$p=$k; //пост. инд. в конец посл-ти

while($x[$p]==$n)//пока не найдем эл-т, отличный от

$p--; //максимального, уменьш. р

$x[$p]++; //увелич р-й эл-т послед-ти

for($i=$p+1;$i<$k;$i++)

$x[$i]=1; //все след-ие делаем единицами

if(correct($x)) //если комбинация нам подходит

{for($i=0;$i<$k;$i++) //выводим слоги с соотв.

{ print $a[$x[$i]-1];}//номерами на экран

echo "<br>";} //переход на новую строку}

Эта функция вызывает prov($x, $y)и correct($x). Функция prov($x, $y)следит за совпадением начальной и конечной комбинациями. Это осуществляется методом простого перебора всех элементов массивов x и y. Если в результате количество совпадающих элементов равно количеству элементов в любом из массивов, то возвращается 0 (и алгоритм размещений с повторениями заканчивает свою работу).