How to convert a Roman numeral to integer in PHP?
How about this:
$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;
which should output 3999 for the supplied $roman
. It seems to work for my limited testing:
MCMXC = 1990MM = 2000MMXI = 2011MCMLXXV = 1975
You might want to do some validation first as well :-)
I am not sure whether you've got ZF or not, but in case you (or any of you who's reading this) do here is my snippet:
$number = new Zend_Measure_Number('MCMLXXV', Zend_Measure_Number::ROMAN);$number->convertTo (Zend_Measure_Number::DECIMAL);echo $number->getValue();
This is the one I came up with, I added the validity check as well.
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; }}