罗马数字包含以下七种字符: 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.
笔者的方法:
时间200ms左右,
思路是
把所有的情况放到哈希表中
每次取一个位
把 i 和 i+1 放一起,试试有没有区配的,有的话把 i 和 i+1 放一起
没有的话,就是 只是计 i
public class Solution
{
public int RomanToInt(string s)
{
char[] c = s.ToCharArray(); //将其转为字符数组
int sum = 0; //值
Hashtable hashtable = new Hashtable();
//7个基本单位
hashtable.Add("I", 1);
hashtable.Add("V", 5);
hashtable.Add("X", 10);
hashtable.Add("L", 50);
hashtable.Add("C", 100);
hashtable.Add("D", 500);
hashtable.Add("M", 1000);
//加上6种情况
hashtable.Add("IV", 4);
hashtable.Add("IX", 9);
hashtable.Add("XL", 40);
hashtable.Add("XC", 90);
hashtable.Add("CD", 400);
hashtable.Add("CM", 900);
/*
* 六种情况
IV 4 IX 9
XL 40 XC 90
CD 400 CM 9000
*/
for (int i = 0; i < c.Length; i++)
{
if (i + 1 < c.Length && hashtable.ContainsKey(c[i].ToString() + c[i + 1].ToString())) //如果发现两位一起能区配的话
{
sum += int.Parse(hashtable[c[i].ToString() + c[i + 1].ToString()].ToString()); //获取值,HashTable的类型都是Object!
i++; //跳两位
}
else
{
sum += int.Parse(hashtable[c[i].ToString()].ToString());
}
}
return sum;
}
}
换成字典
public class Solution
{
public int RomanToInt(string s)
{
char[] c = s.ToCharArray(); //将其转为字符数组
int sum = 0; //值
Dictionary<string, int> dictionary = new Dictionary<string, int>();
//7个基本单位
dictionary.Add("I", 1);
dictionary.Add("V", 5);
dictionary.Add("X", 10);
dictionary.Add("L", 50);
dictionary.Add("C", 100);
dictionary.Add("D", 500);
dictionary.Add("M", 1000);
//加上6种情况
dictionary.Add("IV", 4);
dictionary.Add("IX", 9);
dictionary.Add("XL", 40);
dictionary.Add("XC", 90);
dictionary.Add("CD", 400);
dictionary.Add("CM", 900);
/*
* 六种情况
IV 4 IX 9
XL 40 XC 90
CD 400 CM 9000
*/
for (int i = 0; i < c.Length; i++)
{
if (i + 1 < c.Length && dictionary.ContainsKey(c[i].ToString() + c[i + 1])) //如果发现两位一起能区配的话
{
sum += dictionary[c[i].ToString() + c[i + 1].ToString()]; //获取值,HashTable的类型都是Object!
i++; //跳两位
}
else
{
sum += dictionary[c[i].ToString()];
}
}
return sum;
}
}
以上两个例子都会进行较多的装箱拆箱,下面主要使用if-else,switch,空间花销较大,但是如果测试例子较多,进行大量计算,时间会相对少一点。
public class Solution
{
public int RomanToInt(string s)
{
int sum = 0; //值
for (int i = 0; i < s.Length; i++)
{
if (i + 1 < s.Length) //如果后面还有别的字符
{
if (s[i] == 'I')
{
int a = 0;
switch (s[i + 1]) //"i%"
{
case 'V': a = 4; i++; break;
case 'X': a = 9; i++; break;
default: a = 1; break;
}
sum += a;
}
else if (s[i] == 'X')
{
int a = 0;
switch (s[i + 1]) //"X%"
{
case 'L': a = 40; i++; break;
case 'C': a = 90; i++; break;
default: a = 10; break;
}
sum += a;
}
else if (s[i] == 'C')
{
int a = 0;
switch (s[i + 1]) //"X%"
{
case 'D': a = 400; i++; break;
case 'M': a = 900; i++; break;
default: a = 100; break;
}
sum += a;
}
else
{
int a = 0;
switch (s[i])
{case 'V': a = 5; break;case 'L': a = 50; break;case 'D': a = 500; break;
case 'M': a = 1000; break;
}
sum += a;
}
}
else
{
int a = 0;
switch (s[i])
{
case 'I': a = 1; break;
case 'V': a = 5; break;
case 'X': a = 10; break;
case 'L': a = 50; break;
case 'C': a = 100; break;
case 'D': a = 500; break;
case 'M': a = 1000; break;
}
sum += a;
}
}
return sum;
}
}
到此这篇关于C#算法之罗马数字转整数的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持易知道(ezd.cc)。