如何在PHP中将罗马数字转换为整数?

kap*_*apa 26 php integer roman-numerals

使用PHP,我想将包含罗马数字的字符串转换为其整数表示.我需要这个,因为我需要对它们进行计算.

关于罗马数字的维基百科

仅识别基本的罗马数字字符就足够了,例如:

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

这意味着最高可能的数字是3999(MMMCMXCIX).我将N用来表示零,除了只支持正整数.

我不能将PEAR库用于罗马数字.

我在SO上发现了一个很好的问题,关于如何测试字符串是否包含有效的罗马数字:

如何只使用正则表达式匹配有效的罗马数字?

编码的最佳方法是什么?

and*_*dyb 35

这个怎么样:

$romans = array(
    'M' => 1000,
    'CM' => 900,
    'D' => 500,
    'CD' => 400,
    'C' => 100,
    'XC' => 90,
    'L' => 50,
    'XL' => 40,
    'X' => 10,
    'IX' => 9,
    'V' => 5,
    'IV' => 4,
    'I' => 1,
);

$roman = 'MMMCMXCIX';
$result = 0;

foreach ($romans as $key => $value) {
    while (strpos($roman, $key) === 0) {
        $result += $value;
        $roman = substr($roman, strlen($key));
    }
}
echo $result;
Run Code Online (Sandbox Code Playgroud)

它应该为所提供的输出3999 $roman.它似乎适用于我的有限测试:

MCMXC = 1990
MM = 2000
MMXI = 2011
MCMLXXV = 1975
Run Code Online (Sandbox Code Playgroud)

你可能也想先做一些验证:-)

  • @akTed 实际上不,他们不能,因为:**1.** 十位字符(_I、X、C 和 M_)最多可以重复 3 次。在第 4 位,您需要从下一个最高的 5 个字符中减去。所以“MDCCCCLXXXXVIIII”是无效号码。( _CCCC 应替换为 CD_ )。**2.** 较大的值后面不应跟着较小的值,因此“MIM”也是无效的。1999 年写作“MCMXCIX”。 (2认同)

ako*_*ond 10

我不确定你是否有ZF,但如果你(或任何正在阅读本文的人)在这里做的是我的片段:

$number = new Zend_Measure_Number('MCMLXXV', Zend_Measure_Number::ROMAN);
$number->convertTo (Zend_Measure_Number::DECIMAL);
echo $number->getValue();
Run Code Online (Sandbox Code Playgroud)


kap*_*apa 10

这是我提出的那个,我也添加了有效性检查.

class RomanNumber {
    //array of roman values
    public static $roman_values=array(
        'I' => 1, 'V' => 5, 
        'X' => 10, 'L' => 50,
        'C' => 100, 'D' => 500,
        'M' => 1000,
    );
    //values that should evaluate as 0
    public static $roman_zero=array('N', 'nulla');
    //Regex - checking for valid Roman numerals
    public static $roman_regex='/^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$/';

    //Roman numeral validation function - is the string a valid Roman Number?
    static function IsRomanNumber($roman) {
         return preg_match(self::$roman_regex, $roman) > 0;
    }

    //Conversion: Roman Numeral to Integer
    static function Roman2Int ($roman) {
        //checking for zero values
        if (in_array($roman, self::$roman_zero)) {
            return 0;
        }
        //validating string
        if (!self::IsRomanNumber($roman)) {
            return false;
        }

        $values=self::$roman_values;
        $result = 0;
        //iterating through characters LTR
        for ($i = 0, $length = strlen($roman); $i < $length; $i++) {
            //getting value of current char
            $value = $values[$roman[$i]];
            //getting value of next char - null if there is no next char
            $nextvalue = !isset($roman[$i + 1]) ? null : $values[$roman[$i + 1]];
            //adding/subtracting value from result based on $nextvalue
            $result += (!is_null($nextvalue) && $nextvalue > $value) ? -$value : $value;
        }
        return $result;
    }
}
Run Code Online (Sandbox Code Playgroud)