Title Description
The description of the topic is shown in the figure below, and its link is shown in: Roman numeral to integer.
Topic understanding
I read Roman numerals from left to right. I found that one Roman numeral represents one, but there are six special two letter combinations that must be combined to read. These contents are the patterns I analyzed for the first time (a bit like pattern recognition).
Therefore, the first writing algorithm is to read from left to right. After reading 1 bit, kick out this bit, and after reading 2 bits, kick out 2 bits. Add up the corresponding values to judge whether the remaining string is empty. If it is empty, it ends, and if not, it continues.
My code
class Solution: def romanToInt(self, s: str) -> int: n = 0 while(s!=''): if len(s) == 1: if s == 'I': n += 1 elif s == 'V': n += 5 elif s == 'X': n += 10 elif s == 'L': n += 50 elif s == 'C': n += 100 elif s == 'D': n += 500 else: n += 1000 s = s[1:] else: if s[0:2] == 'IV': n += 4 s = s[2:] elif s[0:2] == 'IX': n += 9 s = s[2:] elif s[0:2] == 'XL': n += 40 s = s[2:] elif s[0:2] == 'XC': n += 90 s = s[2:] elif s[0:2] == 'CD': n += 400 s = s[2:] elif s[0:2] == 'CM': n += 900 s = s[2:] else: if s[0] == 'I': n += 1 elif s[0] == 'V': n += 5 elif s[0] == 'X': n += 10 elif s[0] == 'L': n += 50 elif s[0] == 'C': n += 100 elif s[0] == 'D': n += 500 elif s[0] == 'M': n += 1000 s = s[1:] return n
You can see that the whole code is very lengthy. When you scan it, you know it must not be very dripping, so you don't talk about it in detail.
Therefore, I then thought about the second implementation process. If we use the dictionary to store the values corresponding to these Roman letters in the dictionary in the form of key value pairs, it will be very convenient for each call. So my second code is very concise and clear: when judging whether the current string is empty or not, directly judge whether its first two digits, that is, s[0:2], are in the dictionary. Here is a trick, that is, there is no need to judge whether its length is more than two digits. If the length is less than two digits, it will naturally be divided into else. Then, the slicing operation of the string is used to kick out the letters that have been considered, and then enter the next cycle.
class Solution: def romanToInt(self, s: str) -> int: n = 0 re = dict() re['I'] = 1 re['V'] = 5 re['X'] = 10 re['L'] = 50 re['C'] = 100 re['D'] = 500 re['M'] = 1000 re['IV'] = 4 re['IX'] = 9 re['XL'] = 40 re['XC'] = 90 re['CD'] = 400 re['CM'] = 900 # re = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000, 'IV':4, # 'IX':9, 'XL':40, 'XC':90, 'CD':400, 'CM':900} while(s!=''): if s[0:2] in re: n += re[s[0:2]] s = s[2:] else: n += re[s[0]] s = s[1:] return n
The running result of the code this time is very good, as shown in the figure below:
Ah ha ha ha ~ ~, this result is better than the result of its official code, so I won't talk about its practice here.
In addition, I saw a solution in the discussion area. I think it's very good. It's something I didn't think of, so I'll talk about it here. That is, in the Roman alphanumeric arrangement mode, the six special combinations are small numbers arranged to the left of large numbers, but under normal circumstances, the numbers represented by the letters on the left are larger. This is a very special mode, which can be used to judge. If the current bit is larger than the one on the right, it is good to read the current bit directly; If the current bit is smaller than the right bit, it means that they are a combination. For this combination, the reading of the current bit is subtraction; Then cycle to the next bit.
The above algorithm can be implemented by the code of LeetCode user pony Ma as follows:
class Solution(object): def romanToInt(self, s): """ :type s: str :rtype: int """ dct = {'M':1000,'D':500,'C':100,'L':50,'X':10,'V':5,'I':1} i,res = 0,0 while i < len(s)-1: if dct[s[i]] < dct[s[i+1]]: res -= dct[s[i]] else: res += dct[s[i]] i += 1 return res+dct[s[-1]]
summary
As much as possible to mine the calculation process, the data itself has some patterns and characteristics. The more you mine, and make use of these patterns and characteristics. Of course, combined with some specific data structures, you will write better and better algorithm programs!