先看LeetCode中对于罗马数字的描述
可以看出每个字符代表唯一数值,并且一般小数字在大数字的右边,如果不符合这条规则则根据图中下面的六条规则来。
首先是自己写的代码,没有巧妙的地方,先是判断每一个字符,接着再判断是否是那些特殊情况中的字符
创建临时变量tmp来储存数值
int romanToInt(char arr[]) {
int tmp = 0;
int i = 0;
while (arr[i] != '\0')
{
if (arr[i] == 'I')
{
tmp += 1;
if (arr[i + 1] == 'X')
{
tmp += 8;
i += 1;
}
else if (arr[i + 1] == 'V')
{
tmp += 3;
i += 1;
}
}
else if (arr[i] == 'X')
{
tmp += 10;
if (arr[i + 1] == 'L')
{
tmp += 30;
i += 1;
}
else if (arr[i + 1] == 'C')
{
tmp += 80;
i += 1;
}
}
else if (arr[i] == 'C')
{
tmp += 100;
if (arr[i + 1] == 'D')
{
tmp += 300;
i += 1;
}
else if (arr[i + 1] == 'M')
{
tmp += 800;
i += 1;
}
}
else if (arr[i] == 'V')
tmp += 5;
else if (arr[i] == 'L')
tmp += 50;
else if (arr[i] == 'D')
tmp += 500;
else if (arr[i] == 'M')
tmp += 1000;
i++;
}
return tmp;
}
接着看见了个感觉很巧妙的方法,链接附在下方,将特殊情况中的字符重新定义,最后转换成单个字符的判断。
public class Solution {
public int RomanToInt(string s) {
s=s.Replace("IV","Y");
s=s.Replace("IX","T");
s=s.Replace("XL","U");
s=s.Replace("XC","R");
s=s.Replace("CD","O");
s=s.Replace("CM","W");
int sum=0;
int i=0;
for (i=0;i<s.Length;i++){
switch (s[i]){
case 'M':
sum+=1000;
break;
case 'W':
sum+=900;
break;
case 'D':
sum+=500;
break;
case 'O':
sum+=400;
break;
case 'C':
sum+=100;
break;
case 'R':
sum+=90;
break;
case 'L':
sum+=50;
break;
case 'U':
sum+=40;
break;
case 'X':
sum+=10;
break;
case 'T':
sum+=9;
break;
case 'V':
sum+=5;
break;
case 'Y':
sum+=4;
break;
case 'I':
sum+=1;
break;
}
}
return sum;
}
}
链接:https://leetcode-cn.com/problems/roman-to-integer/solution/c-ti-huan-fa-jia-swtich-by-zapquiyou/
然后来分析官方给的答案
先是创建一个特征数组symbolValues,利用大写字母的ascii码值刚好是26个字母
例如‘A’ - ‘A’ 为0‘Z’ - ‘A’为25,一共26个元素。
然后就是求出需要转换的罗马字符长度,储存在n里面。
接着就是通过循环来叠加数值存放到ans里,然后根据题目的六种特殊情况,是小的放在大的左边,所以我们可以比较大小,可以通过减的方式来算出最终答案,思路如下