За последние 24 часа нас посетили 22899 программистов и 1235 роботов. Сейчас ищут 695 программистов ...

Преобразование арабских цифр в римские

Тема в разделе "Решения, алгоритмы", создана пользователем poisk, 2 мар 2008.

  1. poisk

    poisk Активный пользователь

    С нами с:
    2 мар 2008
    Сообщения:
    1
    Симпатии:
    0
    Срочно понадобилась функция преобразования арабских (обычных) цифр в римские (латинские). В интернете нашел только на Паскале, а для PHP - нету. Пришлось писать самому, оцените, пожалуйста, г-да профессионалы.
    А вот как можно сделать обратную конвертацию сможете подсказать? И как можно еще более оптимизировать и упростить этот код?
    Самая большая конверируемая цифра - 3999, дальше даже Википедия не знает: http://ru.wikipedia.org/wiki/Римские_цифры
    PHP:
    1.  
    2. function to_roman($num_query) {
    3.  
    4.   $num = intval($num_query);
    5.   if (!$num) {
    6.         return($num_query);
    7.         die;
    8.         }
    9.   if ($num >= 4000) {
    10.         return($num_query);
    11.         die;
    12.         }
    13.  
    14.   $roman = array (
    15.         "0" => array(
    16.                     "1" => "I", //1
    17.                     "2" => "II",
    18.                     "3" => "III",
    19.                     "4" => "IV",
    20.                     "5" => "V", //5
    21.                     "6" => "VI",
    22.                     "7" => "VII",
    23.                     "8" => "VIII",
    24.                     "9" => "IX",
    25.                     "0" => ""  
    26.                     ),
    27.  
    28.         "1" => array(
    29.                     "1" => "X", //10
    30.                     "2" => "XX",
    31.                     "3" => "XXX",
    32.                     "4" => "XL",
    33.                     "5" => "L", //50
    34.                     "6" => "LX",
    35.                     "7" => "LXX",
    36.                     "8" => "LXXX",
    37.                     "9" => "XC",
    38.                     "0" => ""
    39.                     ),
    40.        
    41.         "2" => array(
    42.                     "1" => "C", //100
    43.                     "2" => "CC",
    44.                     "3" => "CCC",
    45.                     "4" => "CD",
    46.                     "5" => "D", //500
    47.                     "6" => "DC",
    48.                     "7" => "DCC",
    49.                     "8" => "DCCC",
    50.                     "9" => "CM",
    51.                     "0" => ""
    52.                     ),
    53.        
    54.         "3" => array(
    55.                    "1" => "M", //1000
    56.                    "2" => "MM",
    57.                    "3" => "MMM"
    58.                     )
    59.  
    60.         );
    61.  
    62.   $numlen = strlen( $num );
    63.   $num_query = "";
    64.   for ($nums=0; $nums < $numlen; $nums++){
    65.  
    66.     $pos = $nums+1;
    67.         $num_interval = @substr($num, -$pos, 1);
    68.         $num_query = @strtr($num_interval, $roman[$nums]).$num_query;
    69.        
    70.   }
    71.        
    72. return($num_query);
    73.    
    74. }
    75.  
    76.  
     
  2. Anonymous

    Anonymous Guest

  3. vasa_c

    vasa_c Активный пользователь

    С нами с:
    22 мар 2006
    Сообщения:
    1.760
    Симпатии:
    0
    Адрес:
    гор.Ленинград
    Ну хотя бы вот это:
    PHP:
    1.                       "1" => "I", //1
    2.                       "2" => "II",
    3.                       "3" => "III",
    4.                       "4" => "IV",
    5.                       "5" => "V", //5
    6.                       "6" => "VI",
    7.                       "7" => "VII",
    8.                       "8" => "VIII",
    9.                       "9" => "IX",
    10.                       "0" => ""
    11.                       ),
    12.  
    Можно упростить до:
    PHP:
    1. Array('', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX')
    Так же все эти последовательности строятся по одному принципу (VII - 7, LXX - 70), только пары символов другие. Здесь тоже можно подумать.
     
  4. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
  5. grin-baks

    grin-baks Новичок

    С нами с:
    24 дек 2018
    Сообщения:
    1
    Симпатии:
    0
    Учу PHP. Задание было преобразовать число от 1 до 2000 в римское. Решил так

    Код (Text):
    1. $x=77;//исходные данные
    2. //приводим число к 4м знакам
    3. $x=sprintf ("%04d",$x);
    4. $y = strlen($x);
    5. //первый символов
    6. $y1=substr ($x,0,1);
    7. $y1=str_replace([0,1,2],["","M","MM"],$y1);
    8. //второй символ
    9. $y2=substr ($x,1,1);
    10. $y2=str_replace([0,1,2,3,4,5,6,7,8,9],["","C","CC","CCC","CD","D","DC","DCC","DCCС","СM"],$y2);
    11. // третий символ
    12. $y3=substr ($x,2,1);
    13. $y3=str_replace([0,1,2,3,4,5,6,7,8,9],["","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"],$y3);
    14. // четвёртый символ
    15. $y4=substr ($x,3,1);
    16. $y4=str_replace([0,1,2,3,4,5,6,7,8,9],["","I","II","III","IV","V","VI","VII","VIII","IX"],$y4);
    17. //собираем строку
    18. echo $y1 . $y2 . $y3 . $y4 ;
     
  6. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
  7. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
  8. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Проверил.
    Deonis, вторая строчка - твой вариант (приведённый к идентичности алгоритма, см ниже).
    Код (Text):
    1. 0.0317 | 3 154 574 шт/сек | 100% |CMXCIX
    2. 0.0223 | 4 484 305 шт/сек | 70 % |CMXCIX
    PHP:
    1. function int2roman($n, $prefix='***') {
    2.     $M = ['','M','MM','MMM'];
    3.     $C = ['','C','CC','CCC','CD','D','DC','DCC','DCCC','CM'];
    4.     $X = ['','X','XX','XXX','XL','L','LX','LXX','LXXX','XC'];
    5.     $I = ['','I','II','III','IV','V','VI','VII','VIII','IX'];
    6.     return ($n > 3999 ? $prefix : '') . ($M[($n % 10000)/1000] ?? '') . $C[($n % 1000)/100] . $X[($n % 100)/10] . $I[($n % 10)];
    7. }