13.罗马数字转换
将0-39999的罗马数字转换成整型数据。
- 了解罗马数的基本元素和构成规则
- 异常数据:负数,大于4000,不符合构造规则的错误数字
算法思路
查表和栈的思想。
一个符号对应一个数值,然后用两个指针从前向后扫描。比如当前指针指向的数为AB,那么A>B时,式子的值为A的值,当A<B时,A的值为-A。一直到整个数字结束。所有字符值加起来,如果某个字符比右边的小,减去它的二倍
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;
}
};