Всегда хочется, чтобы интерфейс программы говорил с тобой по-русски. В данной заметке я рассмотрю склонение имен существительных по числу. Как вы увидите, сделать это будет несложно. Почему тогда множество сайтов и программ не умеют этого делать, выдавая пользователям неправильные, с точки зрения русского языка, фразы? Почему даже в таких программах, как Microsoft Word, вместо «3 слова», нам приходится читать «Слов: 3»? Все дело в природной лени программистов. Алгоритм склонения существительных по числу прост. Всего может быть четыре случая. Для примера, будем склонять по числу слово «комментарий»: 1 случай. Число равно нулю. Этот случай можно обработать по вкусу, например: «ни одного комментария», «нет комментариев» и т.п. Но ни в коем случае нельзя писать «0 комментариев», ибо такая форма не употребляется в обычной человеческой речи. 2 случай. Число равно единице, либо остаток от деления на 10 равен единице, но число не равно 11. В этом случае, наш пример примет следующий вид: «n комментарий», где n — число комментариев. 3 случай. Остаток от деления на 10 числа больше одного, но меньше пяти, а остаток от деления на 100 не равен 12, 13 и 14. К этим интервалам относятся числа 22, 23, 54, 2, 3, 173 и т.д. Исключения для этого случая составляют числа 12, 13, 14. Наш пример становится следующим: «n комментария». 4 случай Все остальные числа. Все оставшиеся числа будут отнесены к отдельной категории. Пример станет таким: «n комментариев». Записав наш пример на языке программирования Perl, получим следующее: sub rus_comments {
# Число
my $n = $_[0];
# Возвращаемая строка
my $str;
# Сразу узнаем остатки от деления
# на 10 и 100, чтобы не вычислять
# при каждом сравнении:
my $nmod10 = $n%10;
my $nmod100 = $n%100;
# Случай 1.
if (!$n)
{
$str = "комментариев нет";
}
# Случай 2.
elsif ( ($n eq 1) or ($nmod10 eq 1 and $nmod100 ne 11))
{
$str = "$n комментарий";
}
# Случай 3.
elsif ( ($nmod10 > 1) and ($nmod10 < 5) and
($nmod100 ne 12 and $nmod100 ne 13 and $nmod100 ne 14))
{
$str = "$n комментария";
}
# Случай 4. Все остальные варианты.
else
{
$str = "$n комментариев";
}
return $str;
} Можно написать и более абстрактную функцию, которая будет применима не только для нашего примера, передавая ей аргументами число и все четыре варианта: sub rus_numeric {
my ($n, $var1, $var2, $var3, $var4) = @_;
my $str;
my $nmod10 = $n%10;
my $nmod100 = $n%100;
if (!$n)
{
$str = $var1;
}
elsif ( ($n eq 1) or ($nmod10 eq 1 and $nmod100 ne 11))
{
$str = $var2;
}
elsif ( ($nmod10 > 1) and ($nmod10 < 5) and
($nmod100 ne 12 and $nmod100 ne 13 and $nmod100 ne 14))
{
$str = $var3;
}
else
{
$str = $var4;
}
return $str;
} Тогда, например, количество строк, можно просклонять следующим образом: rus_numeric($n, "нет строк", "$n строка", "$n строки", "$n строк"); Для совсем ленивых, на PHP такая же функция будет выглядеть следующим образом: function rus_numeric ( $n, $var1, $var2, $var3, $var4 ) {
$nmod10 = $n%10;
$nmod100 = $n%100;
$str;
if (!$n)
{
$str = $var1;
} elseif ( ($n == 1) || ($nmod10 == 1 && $nmod100 != 11))
{
$str = $var2;
} elseif ( ($nmod10 > 1) && ($nmod10 < 5)
&& ($nmod100 != 12 && $nmod100 != 13 && $nmod100 != 14))
{
$str = $var3;
} else
{
$str = $var4;
}
return $str;
} Пример использования: rus_numeric($n, "нет строк", "$n строка", "$n строки", "$n строк"); Относитесь с уважением к пользователям ваших приложений, не ленитесь учить свои программы говорить по-русски. Ссылка по теме: Артемий Лебедев, «§ 98. Здравствуйте, с вами говорит робот>».
|