## 一.题目描述
Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
## 二.题目分析
还是先总结一下罗马数字,这是网上找到的一些解释:
罗马数字是最古老的数字表示方式,比阿拉伯数组早2000多年,起源于罗马…
罗马数字有如下符号:
基本字符: I V X L C D M
对应阿拉伯数字 :1 5 10 50 100 500 1000
计数规则: 相同的数字连写,所表示的数等于这些数字相加得到的数,例如:`III = 3`小的数字在大的数字右边,所表示的数等于这些数字相加得到的数,例如:`VIII = 8`小的数字,限于(I、X和C)在大的数字左边,所表示的数等于大数减去小数所得的数,例如:`IV = 4`正常使用时,连续的数字重复不得超过三次在一个数的上面画横线,表示这个数扩大`1000`倍。
**题目思路**,从输入字符串的第一个字符开始(从前向后遍历罗马数字),假设有一个临时变量`k`,结果存放在`result`变量中,算法执行过程中分为以下三种情况:
如果当前字符所对应的数字比前一位字符小,那么就可以先将临时变量的值`k`加到结果`result`中,然后开始下一段记录。比如`VI = 5 + 1`,此时当前为为`'I'`,小于前一位`'V'`,又`k = 5`,当前位对应的数值`curr = 1`,则结果更新为:`result = k + curr`,然后更新临时变量`k = curr`。
如果当前字符所对应的数字和上一个字符一样,那么临时变量`k`加上这个字符。比如`XXX = 30`,在此过程中`k = 10 + 10 + 10`。
如果当前字符所对应的数字比前一位字符大,意味着这一段的值应该是当前这个值减去前面累加的临时变量`k`中的值,比如`IIV = 5 – 2`。
## 三.示例代码
~~~
class Solution
{
public:
int getRomanValue(char c) {
switch (c) {
case 'I': return 1;
case 'V': return 5;
case 'X': return 10;
case 'L': return 50;
case 'C': return 100;
case 'D': return 500;
case 'M': return 1000;
default: return 0;
}
}
int romanToInt(string s)
{
if (s.size() < 1) return -1;
int result = 0;
int temp = getRomanValue(s[0]);
int k = temp;
for (size_t i = 1; i < s.size(); i++)
{
int curr = getRomanValue(s[i]);
if (temp > curr)
{
result += k;
k = curr;
}
else if (temp == curr)
k = k + curr;
else
k = curr - k;
temp = curr;
}
result += k;
return result;
}
};
~~~
## 四.小结
网上有更简便的思路:
~~~
class Solution {
public:
int romanToInt(string s) {
int map[26];
map['I' - 'A'] = 1; map['V' - 'A'] = 5; map['X' - 'A'] = 10; map['L' - 'A'] = 50;
map['C' - 'A'] = 100; map['D' - 'A'] = 500; map['M' - 'A'] = 1000;
int res = 0, n = s.size();
s.push_back(s[n - 1]);
for (int i = 0; i < n; i++)
{
if (map[s[i] - 'A'] >= map[s[i + 1] - 'A'])
res += map[s[i] - 'A'];
else res -= map[s[i] - 'A'];
}
return res;
}
};
~~~
对应的题目:Integer to Roman。
- 前言
- 2Sum
- 3Sum
- 4Sum
- 3Sum Closest
- Remove Duplicates from Sorted Array
- Remove Duplicates from Sorted Array II
- Search in Rotated Sorted Array
- Remove Element
- Merge Sorted Array
- Add Binary
- Valid Palindrome
- Permutation Sequence
- Single Number
- Single Number II
- Gray Code(2016腾讯软件开发笔试题)
- Valid Sudoku
- Rotate Image
- Power of two
- Plus One
- Gas Station
- Set Matrix Zeroes
- Count and Say
- Climbing Stairs(斐波那契数列问题)
- Remove Nth Node From End of List
- Linked List Cycle
- Linked List Cycle 2
- Integer to Roman
- Roman to Integer
- Valid Parentheses
- Reorder List
- Path Sum
- Simplify Path
- Trapping Rain Water
- Path Sum II
- Factorial Trailing Zeroes
- Sudoku Solver
- Isomorphic Strings
- String to Integer (atoi)
- Largest Rectangle in Histogram
- Binary Tree Preorder Traversal
- Evaluate Reverse Polish Notation(逆波兰式的计算)
- Maximum Depth of Binary Tree
- Minimum Depth of Binary Tree
- Longest Common Prefix
- Recover Binary Search Tree
- Binary Tree Level Order Traversal
- Binary Tree Level Order Traversal II
- Binary Tree Zigzag Level Order Traversal
- Sum Root to Leaf Numbers
- Anagrams
- Unique Paths
- Unique Paths II
- Triangle
- Maximum Subarray(最大子串和问题)
- House Robber
- House Robber II
- Happy Number
- Interlaving String
- Minimum Path Sum
- Edit Distance
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock II
- Best Time to Buy and Sell Stock III
- Best Time to Buy and Sell Stock IV
- Decode Ways
- N-Queens
- N-Queens II
- Restore IP Addresses
- Combination Sum
- Combination Sum II
- Combination Sum III
- Construct Binary Tree from Inorder and Postorder Traversal
- Construct Binary Tree from Preorder and Inorder Traversal
- Longest Consecutive Sequence
- Word Search
- Word Search II
- Word Ladder
- Spiral Matrix
- Jump Game
- Jump Game II
- Longest Substring Without Repeating Characters
- First Missing Positive
- Sort Colors
- Search for a Range
- First Bad Version
- Search Insert Position
- Wildcard Matching