C#算法之罗马数字转整数
程序员文章站
2022-06-10 09:16:22
罗马数字转整数罗马数字包含以下七种字符:i,v,x,l,c,d和m。字符 数值i 1v 5x 10l...
罗马数字转整数
罗马数字包含以下七种字符: 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#算法之罗马数字转整数的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持。