Перевод целого числа в текст

Wahtel

Новичок
Всем привет, получил тестовое задание, звучит оно так:

"Написать решение c использованиемООП, которое позволяет переводить целые числа в каком-нибудь диапазоне (cмиллионами включительно) в текст ( разговорный) на трех языках (рус., англ., укр.) "

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

MiksIr

miksir@home:~$
ну типа стратегия какая-нить для языков, а сами классы еще в фабричный метод завернуть ;)
Тестовое задание же ;)
 

Вурдалак

Продвинутый новичок
Нормально всё. Пишешь интерфейс и реализацию, которая делает HTTP-запрос к http://www.num2word.ru. И всё, не придерёшься, пусть препод жуёт галстук.

UPD: ах ж твою, там JavaScript. Придётся ещё Selenium заюзать.
 

MiksIr

miksir@home:~$
Там ухраинского нет, придется еще интерфейс в переводчик делать ;)
 

Redjik

Джедай-мастер
кстати народ, а же таки погуглил нормально проблему.... и ведь хрень одна попадается, не нашел серебряной пули.
поясняю.

я точно знаю, что правила в Рус, Англ, Укр языках для числительных примерно одинаковы.
но вот хз, чо там в китайском или арабском

сделали, скажем, для пары языков, добавился какой-нить язык, где вообще все по-другому! во, немецкий например (отличия не радикальные, но все же есть)

пока в душе торчал, продумывал алгоритм с построением дерева :D можно сделать почти универсально для любого языка, но вот как конфиг (набор правил) удобочитаемым сделать, так и не придумал...
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
ой, да я делал crm когда-то, там и японский с китайским были,
прописываются правила трансляции, морочно, конечно, но это ж вопрос бюджета, а не алгоритма
 

WMix

герр M:)ller
Партнер клуба
Redjik, у меня есть 2 функции нем и рус, но на самом деле от того что 32 цвай унд драйсихь (порядок слов сменился) никакого отличия, как было "тридцать" и "два" так и осталось (кста. они еще говорят 16 сотен к примеру, а не "тысяча" "шесть" "сот", но только если год, ну и после миллиона идет по разному), а вот множественное число я вынес в отдельную функцию, в русском 1 2 и 5 различны яб подарил бы но топикстартер хочет в ооп и просил не давать кода
 
Последнее редактирование:

peon

Lok'tar ogar
Нормально всё. Пишешь интерфейс и реализацию, которая делает HTTP-запрос к http://www.num2word.ru. И всё, не придерёшься, пусть препод жуёт галстук.

UPD: ах ж твою, там JavaScript. Придётся ещё Selenium заюзать.
или просто посмотреть сценарий на том сайте и сделать по аналогии

или использовать API другого приложения, как видимо хотел Вурдлак
http://api.morpher.ru/WebService.asmx/Propis?n=235&unit=рублей
 
  • Like
Реакции: WMix

Wahtel

Новичок
Я нашел в интернете одну функцию которая в принципе делает то, что мне нужно но правда только на русском, но пока я думаю этого будет достаточно, я хочу эту функцию:
Код:
<?php
/**
* Возвращает сумму прописью
* @author runcore
* @uses morph(...)
*/
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[]= morph($v,$unit[$uk][0],$unit[$uk][1],$unit[$uk][2]);
        } //foreach
    }
    else $out[] = $nul;
    $out[] = morph(intval($rub), $unit[1][0],$unit[1][1],$unit[1][2]); // rub
    $out[] = $kop.' '.morph($kop,$unit[0][0],$unit[0][1],$unit[0][2]); // kop
    return trim(preg_replace('/ {2,}/', ' ', join(' ',$out)));
}

/**
* Склоняем словоформу
* @ author runcore
*/
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;
}



echo num2str(859);
перевести под ООП, с этим возникли некоторые затруднения, я вижу себе это так:
Я создаю класс, в нем будет три таких функции только адаптированные под три языка, и после этих трех функция идет вторая функция этого скрипта morph, которая как я понял фильтрует и проверяет данные, проблема в том, что в некоторых местах мне этот скрипт не совсем ясен, поэтому обращаюсь к вам)
Я сделал так:

Код:
<?php

class numberTransfer
{
    public 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($uah,$kop) = explode('.',sprintf("%015.2f", floatval($num)));
        $out = array();
        if (intval($uah)>0) {
            foreach(str_split($uah,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[]= morph($v,$unit[$uk][0],$unit[$uk][1],$unit[$uk][2]);
            } //foreach
        }
        else $out[] = $nul;
       
        $out[] = morph(intval($uah), $unit[1][0],$unit[1][1],$unit[1][2]); // rub
       
        $out[] = $kop.' '.morph($kop,$unit[0][0],$unit[0][1],$unit[0][2]); // kop
       
        return trim(preg_replace('/ {2,}/', ' ', join(' ',$out)));
       
        return $num;
    } // end num2str
   
    public 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;
    }
   
}
Я уже работал с ООП, но не так много как хотелось бы, чувствую себя пока не очень уверенно, и мне кажется что, то что я сделал это не то что бы ООП, я просто создал класс и этим двум функциям присвоил public, буду благодарен если вы глянете и скажете что тут надо сделать, для того что этот код стал похож на ООП и желательно еще и работал)
 

Wahtel

Новичок
Запускал, ноль на массу, я верю что это бред)
Я понимаю это так, что функция num2str должна служить конструктором, но не понимаю как это реализовать.
 

WMix

герр M:)ller
Партнер клуба
peon, это работает!
Wahtel, это нивкоем случае не конструктор. на конструктор можно передать макс. число возможно язык. а далее с полученым обьектом можно сотворить тоТекст().
 

WMix

герр M:)ller
Партнер клуба
восемьсот пятьдесят девять гривен 00 копеек
 

WMix

герр M:)ller
Партнер клуба
Wahtel, ты сомневаешься в том, что только у тебя функция стала методом?
 

WMix

герр M:)ller
Партнер клуба
Redjik, ну может быть
- меня этото поезд до москвы довезет?
- нет!,
-а меня?
 
Сверху