Число в строчное представление

hell0w0rd

Продвинутый новичок
Только что помогал на экзамене человеку по плюсам, но думаю код будет понятен любому, задачка:
дано например 1345, на выходе должно быть тысяча триста сорок пять
То, что я написал действует так:
Пробуем привести число к строке, если не получается - берем бОльший разряд числа и разделяем число на две части - 1000 и 345
Для 1000 у нас есть строчное представление, 345 отправляем в такую же функцию, где происходит то же самое.

Собственно вопрос в том, что делать например с большими числами. Если оставить все как есть - в simpleIntToString надо захардкорить все десятки - десять тысяч, сто тысяч, или же можно смотреть на разрядность и в зависимости от нее получать число. Хотя тут возникает проблема с "десять тысяча", то есть правилами русского языка.

В общем интересно как сделали бы вы:)
 

billyrubin

Новичок
Видел когда-то такой вариант. Работал и для бОльших чисел, умел подстраиваться под род и падеж (правда, в нем тоже не все было хорошо):
  • хардкодим массивы (по роду) слов-числительных для 1-9, типа: array('один', 'одна', 'одно');
  • хардкодим слова-числительные для 10-19, 10*(2-9), 100*(1-9). По родам и падежам тут ничего не изменяется, так что просто: array('десять', 'одиннадцать', …);
  • хардкодим массивы (по падежам) слов для больших разрядов, типа: array('тысяча', 'тысячи', 'тысяч'), array('миллиард', 'миллиарда', 'миллиардов') и т. п. — это будут окончания триад;
  • делим исходное число на триады (допишем нулями слева до кратного 3) и собираем потихоньку, начиная с младшей триады: слово-числительное + окончание триады…
Как-то так…
 
Последнее редактирование:

WMix

герр M:)ller
Партнер клуба
а вот еще нашел в одном из проектов
PHP:
  protected function morph($n, $f1, $f2, $f5) {
     $n = abs(intval($n)) % 100;
     if ($n>10 && $n<20) return $f5;
     $n = $n % 10;
     if ($n>1 && $n<5) return $f2;
     if ($n==1) return $f1;
     return $f5;
   }
    protected function num2str( $num ) {
        $nul='ноль';
        $ten=array(
                array('','один','два','три','четыре','пять','шесть','семь', 'восемь','девять'),
                array('','одна','две','три','четыре','пять','шесть','семь', 'восемь','девять'),
        );
        $a20=array('десять','одиннадцать','двенадцать','тринадцать','четырнадцать' ,'пятнадцать','шестнадцать','семнадцать','восемнадцать','девятнадцать');
        $tens=array(2=>'двадцать','тридцать','сорок','пятьдесят','шестьдесят','семьдесят' ,'восемьдесят','девяносто');
        $hundred=array('','сто','двести','триста','четыреста','пятьсот','шестьсот', 'семьсот','восемьсот','девятьсот');
        $unit=array( // Units
                array('копейка' ,'копейки' ,'копеек',    1),
                array('рубль'  ,'рубля'  ,'рублей'    ,0),
                array('тысяча'  ,'тысячи'  ,'тысяч'    ,1),
                array('миллион' ,'миллиона','миллионов' ,0),
                array('миллиард','милиарда','миллиардов',0),
        );
        //
        list($rub,$kop) = explode('.',sprintf("%015.2f", floatval($num)));
        $out = array();
        if (intval($rub)>0) {
            foreach(str_split($rub,3) as $uk=>$v) { // by 3 symbols
                if (!intval($v)) continue;
                $uk = sizeof($unit)-$uk-1; // unit key
                $gender = $unit[$uk][3];
                list($i1,$i2,$i3) = array_map('intval',str_split($v,1));
                // mega-logic
                $out[] = $hundred[$i1]; # 1xx-9xx
                if ($i2>1) $out[]= $tens[$i2].' '.$ten[$gender][$i3]; # 20-99
                else $out[]= $i2>0 ? $a20[$i3] : $ten[$gender][$i3]; # 10-19 | 1-9
                // units without rub & kop
                if ($uk>1) $out[]= $this->morph($v,$unit[$uk][0],$unit[$uk][1],$unit[$uk][2]);
            }
        }
        else $out[] = $nul;
        $out[] = $this->morph(intval($rub), $unit[1][0],$unit[1][1],$unit[1][2]); // rub
        $out[] = $kop.' '.$this->morph($kop,$unit[0][0],$unit[0][1],$unit[0][2]); // kop
        return trim(preg_replace('/ {2,}/', ' ', join(' ',$out)));
    }
 
Сверху