NetSago
Вход
Войти

Как присоединиться?
Меню
Главная
События
 Заметки
Статьи
Теги
Поиск
О Проекте
Ссылки
Наше
RSS События по RSS
RSS Заметки по RSS
netsago NetSago
Популярное
Руководство по получению прибыли от Свободных и Открытых Проектов by Джон Эндрюс

Восстановление удаленных текстовых файлов в ФС ext3 by scamelscrud

Заметки — Программное склонение существительных по числу.
Назад в Заметки

Программное склонение существительных по числу.
n0xi0uzz



Теги: russian perl interfaces



Всегда хочется, чтобы интерфейс программы говорил с тобой по-русски. В данной заметке я рассмотрю склонение имен существительных по числу. Как вы увидите, сделать это будет несложно. Почему тогда множество сайтов и программ не умеют этого делать, выдавая пользователям неправильные, с точки зрения русского языка, фразы? Почему даже в таких программах, как 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. Здравствуйте, с вами говорит робот>».

Язык
English/Английский
Поиск
Расширенный Поиск
Ошиблись?
Если вы обнаружили ошибку на сайте, пожалуйста, сообщите нам о ней.
Посчитали
13 / 670
К нам сегодня зашли 90 роботов. Они хотят убить всех человеков.

Зарегистрированных пользователей: 0
Онлайн: 0

Время генерации: 0.010 с
NetSago.v2.β © [2006;∞)  Neunica