罗马数字转整数
罗马数字包含以下七种字符: 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 到 3999 的范围内。
示例 1:
输入: “III”
输出: 3
示例 2:
输入: “IV”
输出: 4
示例 3:
输入: “IX”
输出: 9
示例 4:
输入: “LVIII”
输出: 58
解释: L = 50, V= 5, III = 3.
示例 5:
输入: “MCMXCIV”
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.
————————————————————————————
粘出自己的辣鸡代码
class Solution {
public:
int romanToInt(string s) {
const char *ch = s.data();
int sum = 0, i=0;
while(i
思路简单,就是不管三七二十一,先加上再说,如果发现倒装的情况,就减双倍的。唯一要注意的就是,别让指针越位。
下面是leecode提供的一种算法;
static const auto io_sync_off=[](){
std::ios::sync_with_stdio(false);
std::cin.tie(NULL);
return 0;
}();
class Solution {
public:
int romanToInt(string s) {
int sum = 0;
int n[s.size()+1];
n[s.size()]=0;
for(int i = 0; i < s.length(); i++){
switch(s[i]){
case 'I': n[i]=1; break;
case 'V': n[i]=5; break;
case 'X': n[i]=10; break;
case 'L': n[i]=50; break;
case 'C': n[i]=100; break;
case 'D': n[i]=500; break;
case 'M': n[i]=1000; break;
default :break;
}
}
//可以用int n[100]; n['I']=1;....表示
for(int i = 0; i < s.length(); i++){
if(n[i] < n[i+1]) {
sum = sum + n[i+1] - n[i];
i++;
}else
sum += n[i];
}
return sum;
}
};
这是第一种,看起来和我的差不多,只是用一个数组把读出来的东西装进去了,然后判断前后之间是否降序,如果不是,那加上后面的减去前面的。如果这道题,I也可以放在C或者M前面,那,这种方法代码会短很多。
static const auto io_sync_off = []()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
return nullptr;
}();
static std::unordered_map mp = {
{'I',1},{'V',5},{'X',10},{'L',50},{'C',100},{'D',500},{'M',1000}
};
class Solution {
public:
int romanToInt(string s) {
int res = 0;
auto it = s.begin();
while (it != s.end()-1)
{
if (mp[*(it+1)] > mp[*it]) res -= mp[*it++];
else res += mp[*it++];
}
res += mp[*it];
return res;
}
};
这种方法和前一种基本是一样的,只是用了一个map,来替换掉了switch语句和数组。
https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html 这是map类的用法。
执行用时为 28 ms 的范例
static int x = [](){
ios::sync_with_stdio(false);
cin.tie(NULL);
return 0;
}();
class Solution {
public:
int romanToInt(string s) {
unordered_map mp;
mp['I'] = 1;
mp['V'] = 5;
mp['X'] = 10;
mp['L'] = 50;
mp['C'] = 100;
mp['D'] = 500;
mp['M'] = 1000;
int b = 0;
int n = 0;
for (int i = s.size() - 1; i >= 0; i--) {
if (mp[s[i]] < b) {
n -= mp[s[i]];
}
else {
n += mp[s[i]];
b = max(b, mp[s[i]]);
}
}
return n;
}
};
这个算法就有点不同了,最大的差别就是它是从后向前迭代的,然后每次用b记录当前出现的最大的值,如果迭代值比它大,加上,并且更新b,否则减去,b不变。
先看到这吧。