Как преобразовать римскую цифру в целое число в PHP? - PullRequest
25 голосов
/ 07 июня 2011

Используя PHP, я хотел бы преобразовать строку, содержащую римское число, в его целочисленное представление.Я нуждаюсь в этом, потому что мне нужно делать вычисления на них.

Википедия по римским цифрам

Достаточно будет распознавать только основные символы римских цифр, например:

$roman_values=array(
    'I' => 1,
    'V' => 5,
    'X' => 10,
    'L' => 50,
    'C' => 100,
    'D' => 500,
    'M' => 1000,
);

Это означает, что максимально возможное число равно 3999 (MMMCMXCIX).Я буду использовать N для представления нуля, за исключением того, что поддерживаются только положительные целые числа.

Я не могу использовать библиотеку PEAR для римских чисел.

Я нашел этот замечательный вопрос о том, как SOчтобы проверить, содержит ли строка действительные римские цифры:

Как сопоставить только действительные римские цифры с регулярным выражением?

Какой будет лучший способ кодированияэто?

Ответы [ 13 ]

0 голосов
/ 07 мая 2015
function Romannumeraltonumber($input_roman){
  $di=array('I'=>1,
            'V'=>5,
            'X'=>10,
            'L'=>50,
            'C'=>100,
            'D'=>500,
            'M'=>1000);
  $result=0;
  if($input_roman=='') return $result;
  //LTR
  for($i=0;$i<strlen($input_roman);$i++){ 
    $result=(($i+1)<strlen($input_roman) and 
          $di[$input_roman[$i]]<$di[$input_roman[$i+1]])?($result-$di[$input_roman[$i]]) 
                                                        :($result+$di[$input_roman[$i]]);
   }
 return $result;
}
0 голосов
/ 02 апреля 2012

Я только что написал это примерно за 10 минут, это не идеально, но, похоже, работает для нескольких тестовых случаев, которые я дал. Я не проверяю, из каких значений можно вычитать, это просто базовый цикл, который сравнивает текущее буквенное значение со следующим в последовательности (если оно существует), а затем либо добавляет значение, либо добавляет вычтенное количество к итогу:

$roman = strtolower($_GET['roman']);

$values = array(
'i' => 1,
'v' => 5,
'x' => 10,
'l' => 50,
'c' => 100,
'd' => 500,
'm' => 1000,
);
$total = 0;
for($i=0; $i<strlen($roman); $i++)
{
    $v = $values[substr($roman, $i, 1)];
    $v2 = ($i < strlen($roman))?$values[substr($roman, $i+1, 1)]:0;

    if($v2 && $v < $v2)
    {
        $total += ($v2 - $v);
        $i++;
    }
    else
        $total += $v;

}

echo $total;
0 голосов
/ 08 июня 2011

Определите свою собственную схему! (Факультативно) * * +1001

function rom2arab($rom,$letters=array()){
    if(empty($letters)){
        $letters=array('M'=>1000,
                       'D'=>500,
                       'C'=>100,
                       'L'=>50,
                       'X'=>10,
                       'V'=>5,
                       'I'=>1);
    }else{
        arsort($letters);
    }
    $arab=0;
    foreach($letters as $L=>$V){
        while(strpos($rom,$L)!==false){
            $l=$rom[0];
            $rom=substr($rom,1);
            $m=$l==$L?1:-1;
            $arab += $letters[$l]*$m;
        }
    }
    return $arab;
}

Вдохновленный ответом andyb

...