一、题目描述:
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符与数值的对应关系如下:
I -> 1, V -> 5, X -> 10, L -> 50, C -> 100, D -> 500, M -> 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。
数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。
这个特殊的规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
1、将罗马数字转换成整数
例:
输入: “MCMXCIV”
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.
2、将整数转换成罗马数字
例:
输入: 1994
输出: “MCMXCIV”
解释: M = 1000, CM = 900, XC = 90, IV = 4.
二、题目分析:
1、罗马数字转整数:
- 由题意可知,如果当前这个罗马数字小于后一个,则减去这个罗马数字对应的整数值,反之则加上对应的值;
- 因此按照这个思路,只要将罗马数字从头遍历到尾,就可以得到相应的整数值。(用switch语句记录每个罗马数字代表的整数值)
2、整数转罗马数字:
- 由题意可知,要把整数转换为罗马数字,我们需要将这个整数的每一个位(个、十、百、千)上的数字,都转化为它所对应的罗马数字,因为罗马数字个、十、百、千位上的数字表示都不一样;
- 则先求出整数的位数(n /= 10),然后再求出每一位对应的整数数字;
- 用switch语句得到数字0~9在罗马数字中的个、十、百、千位所对应的罗马数字。
三:代码详解:
1、罗马数字转整数:
int val(char s)//记录罗马数字对应的整数值
{
int val = 0;
switch (s)
{
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;
}
return val;
}
int romanToInt(string s)
{
int len = s.size();
int sum = 0;
for (int i = 0; i < len; i++)
{
if (val(s[i]) >= val(s[i + 1])) //大于等于后一个则加
{
sum += val(s[i]);
}
else //小于后一个则减
{
sum -= val(s[i]);
}
}
return sum;
}
int main()
{
string s = "MMMCMXCIX";
cout << romanToInt(s) << endl;
return 0;
}
2、整数转罗马数字:
int size(int n) //求整数的位数
{
int size = 0;
while (n)
{
n /= 10;
size++;
}
return size;
}
string str(int _size,int m) //数字0~9在罗马数字中的个、十、百、千位所对应的罗马数字
{
string str;
if (_size == 1) //个位
{
switch (m)
{
case 1: str = "I"; break;
case 2: str = "II"; break;
case 3: str = "III"; break;
case 4: str = "IV"; break;
case 5: str = "V"; break;
case 6: str = "VI"; break;
case 7: str = "VII"; break;
case 8: str = "VIII"; break;
case 9: str = "IX"; break;
}
}
else if (_size == 2) //十位
{
switch (m)
{
case 1: str = "X"; break;
case 2: str = "XX"; break;
case 3: str = "XXX"; break;
case 4: str = "XL"; break;
case 5: str = "L"; break;
case 6: str = "LX"; break;
case 7: str = "LXX"; break;
case 8: str = "LXXX"; break;
case 9: str = "XC"; break;
}
}
else if (_size == 3) //百位
{
switch (m)
{
case 1: str = "C"; break;
case 2: str = "CC"; break;
case 3: str = "CCC"; break;
case 4: str = "CD"; break;
case 5: str = "D"; break;
case 6: str = "DC"; break;
case 7: str = "DCC"; break;
case 8: str = "DCCC"; break;
case 9: str = "CM"; break;
}
}
else if (_size == 4) //千位
{
switch (m)
{
case 1: str = "M"; break;
case 2: str = "MM"; break;
case 3: str = "MMM"; break;
}
}
return str;
}
string intToRoman(int n)
{
int _size = size(n);//整形数字的位数
string _s;
if (_size > 4)
{
return 0;
}
while (_size > 0)
{
int k = pow(10, _size-1);
int m = n/k;
_s += str(_size, m);
n %= k;
_size--;
}
return _s;
}
int main()
{
int n = 1994;
cout << intToRoman(n) << endl;
}