罗马字符与整数互转

Given a roman numeral, convert it to an integer. Input is guaranteed
to be within the range from 1 to 3999.

思路

罗马数字有如下符号:

基本字符IVXLCDM
对应阿拉伯数字1510501005001000

1~9: {“I”, “II”, “III”, “IV”, “V”, “VI”, “VII”, “VIII”, “IX”};

10~90: {“X”, “XX”, “XXX”, “XL”, “L”, “LX”, “LXX”, “LXXX”, “XC”};

100~900: {“C”, “CC”, “CCC”, “CD”, “D”, “DC”, “DCC”, “DCCC”, “CM”};

1000~3000: {“M”, “MM”, “MMM”}.

计数规则:
相同的数字连写,所表示的数等于这些数字相加得到的数,例如:III = 3
小的数字在大的数字右边,所表示的数等于这些数字相加得到的数,例如:VIII = 8
小的数字,限于(I、X和C)在大的数字左边,所表示的数等于大数减去小数所得的数,例如:IV = 4
正常使用时,连续的数字重复不得超过三次
在一个数的上面画横线,表示这个数扩大1000倍(本题只考虑3999以内的数,所以用不到这条规则)

其次,罗马数字转阿拉伯数字规则(仅限于3999以内):

从前向后遍历罗马数字,如果某个数比前一个数小,则加上该数。反之,减去前一个数的两倍然后加上该数.

代码如下:

/**
 * [romanToInt description] 罗马字符转换为整数
 * @param  [type] $str 罗马字符
 * @return [type]      转化后的整数
 */
function romanToInt($str) {
    if (strlen($str) < 1) 
        return false;
    $res = charToNumber($str[0]);
    for ($i = 1; $i < strlen($str); $i++) {
        $pre = charToNumber($str[$i - 1]);
        $cur = charToNumber($str[$i]);
        if ($pre < $cur) {
            $res += $cur - 2 * $pre;
        } else {
            $res += $cur;
        }
    }
    return $res;
}

// 第二种方法
function romanToInt2($str) {
    if (strlen($str) < 1) 
        return false;
    $res = 0;
    for ($i = 0; $i < strlen($str); $i++) {
        $val = charToNumber($str[$i]);
        if ($i == strlen($str) - 1 || charToNumber($str[$i + 1]) <= $val)
            $res += $val;
        else 
            $res -= $val;
    }
    return $res;
}

/**
 * [charToNumber description] 单个罗马字符转化为对应的数字
 * @param  [type] $char 单个罗马字符
 * @return [type]       对应的整数
 */
function charToNumber($char) {
    switch ($char) {
        case 'I': return 1; break;  
        case 'V': return 5; break;
        case 'X': return 10; break;
        case 'L': return 50; break;
        case 'C': return 100; break;
        case 'D': return 500; break;
        case 'M': return 1000; break;
    }
    return 0;
}

echo romanToInt1('IX');
echo romanToInt2('IX');

整数转为罗马字符数字:

/**
 * 整数转换为罗马字符数字
 * @param  Integer $number 要转化的整数
 * @return String         转化后的罗马字符数字
 */
function intToRoman($number) {
    $values = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
    $romanChars = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"];
    $res = '';
    for($i = 0; $i < count($values); $i++) {
        while ($number >= $values[$i]) {
            $number -= $values[$i];
            $res .= $romanChars[$i];
        }
    }
    return $res;
}

// 方法二
function intToRoman2($number) {
    $M = ["", "M", "MM", "MMM"];
    $C = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"];
    $X = ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"];
    $I = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"];
    return $M[$number / 1000] . $C[floor($number % 1000 / 100)] . $X[floor($number % 100 / 10)] . $I[floor($number % 10)];
}
echo intToRoman(1001);
echo intToRoman2(1001);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值