C#算法之罗马数字转整数
罗马数字转整数
罗马数字包含以下七种字符: 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#算法之罗马数字转整数的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持。