13.罗马数字转换

将0-39999的罗马数字转换成整型数据。

  1. 了解罗马数的基本元素和构成规则
  2. 异常数据:负数,大于4000,不符合构造规则的错误数字

算法思路

  1. 查表和栈的思想。
    一个符号对应一个数值,然后用两个指针从前向后扫描。比如当前指针指向的数为AB,那么A>B时,式子的值为A的值,当A<B时,A的值为-A。一直到整个数字结束。

  2. 所有字符值加起来,如果某个字符比右边的小,减去它的二倍

    int roman(char c)
    {
    int val=0;
    switch (c)
    {
    case ‘I’:
    val=1;
    break;
    case ‘V’:
    val=5;
    break;
    case ‘X’:
    val=10;
    break;
    case ‘L’:
    val=50;
    break;
    case ‘C’:
    val=100;
    break;
    case ‘D’:
    val=500;
    break;
    case ‘M’:
    val=1000;
    break;
    default:
    val=0;
    }
    return val;
    }

    int romanToInt(string s) {
    int i=0;
    int val=0;

    while (i+1<s.length())
    {
    int current=roman(s[i]);
    int next=roman(s[i+1]);

    if (current<next)
    {
    val-=current;
    }
    else
    {
    val+=current;
    }
    i++;
    }
    val+=roman(s[i]);

    return val;

    }

这个算法比较纠结的地方在于循环条件,如何控制循环条件使它既能满足在最后一个不溢出,又能满足只有一个字符的时候也能计算。

我采用的方法是用i+1<s.length()来控制指针不溢出,但是这样会漏掉最后一个s[i]的计算,同时当只有一个字符的时候不满足判断条件也会跳过,所以在最后加上一句val+=roman(s[i])

在评论中学到这种情况可以将指针从后向前移动for (int i = s.length() - 1; i >= 0; i--)

整型数转罗马数字

直接将0-4000对应的符号表全部列出,然后换算。

class Solution {
public:
string intToRoman(int num) {
    char* c[4][10]={
        {"","I","II","III","IV","V","VI","VII","VIII","IX"},
        {"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"},
        {"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"},
        {"","M","MM","MMM"}
    };
    string roman;
    roman.append(c[3][num / 1000 % 10]);
    roman.append(c[2][num / 100 % 10]);
    roman.append(c[1][num / 10 % 10]);
    roman.append(c[0][num % 10]);
     
    return roman;
}
};