今天看的是罗马数字和阿拉伯数字之间的转换,主要是字符串和数字之间的处理,话不多说,先来看整数到罗马数字:
题目描述:
Given an integer, convert it to a roman numeral.
Input is guaranteed to be within the range from 1 to 3999.
因为罗马数字有一个规定,即同一个字母不会出现超过3次,也就说没有MMMM(4000)这样的表示,这就限定了范围
解法如下:
class Solution {
public:
string intToRoman(int num) {
string str;
string symbol[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
int value[]= {1000,900,500,400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
for(int i=0;num!=0;++i)
{
while(num>=value[i])
{
num-=value[i];
str+=symbol[i];
}
}
return str;
}
};
主要过程是先判断最大能表示这个数字的罗马字母,然后一步一步往下即可,注意在初始化对应表的时候,罗马数字有独特的减法,先列举出来就可以减少很多讨论上的麻烦(实际上全部列举出来也可以解决且更好理解)。
之后再看罗马数字到整数的转换:
class Solution {
public:
int romanToInt(string s) {
int res = 0;
map<char, int> m{{'I', 1}, {'V', 5}, {'X', 10}, {'L', 50}, {'C', 100}, {'D', 500}, {'M', 1000}};
for (int i = 0; i < s.size(); ++i) {
int val = m[s[i]];
if (i == s.size() - 1 || m[s[i+1]] <= m[s[i]])
res += val;
else res -= val;
}
return res;
}
};
这里可以像之前一样不用map,但是map在这里就很好用。主要思路是一个一个字符读取,如果发现到后一个字符比前一个字符大的话,就把前面已经累积的值被后面这个大的值减去即可。如8(IIX)这个数字,先得到2,最后得到10,发现10(X)比I(1)大,就用10减去2即可。