No.012 Integer to Roman
12. Integer to Roman
- Total Accepted: 71315
- Total Submissions: 176625
- Difficulty: Medium
Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999.
思路:
首先,我们得弄清楚罗马数字的计数方式。根据维基百科的介绍:https://zh.wikipedia.org/wiki/%E7%BD%97%E9%A9%AC%E6%95%B0%E5%AD%97
罗马数字共有7个,即I(1)、V(5)、X(10)、L(50)、C(100)、D(500)和M(1000)。按照下述的规则可以表示任意正整数。需要注意的是罗马数字中没有“0”,与进位制无关。一般认为罗马数字只用来记数,而不作演算。
- 重复数次:一个罗马数字重复几次,就表示这个数的几倍。
- 右加左减:
- 在较大的罗马数字的右边记上较小的罗马数字,表示大数字加小数字。
- 在较大的罗马数字的左边记上较小的罗马数字,表示大数字减小数字。
- 左减的数字有限制,仅限于I、X、C。比如45不可以写成VL,只能是XLV
- 但是,左减时不可跨越一个位值。比如,99不可以用IC({\displaystyle 100-1}
)表示,而是用XCIX({\displaystyle [100-10]+[10-1]}
)表示。(等同于阿拉伯数字每位数字分别表示。)
- 左减数字必须为一位,比如8写成VIII,而非IIX。
- 右加数字不可连续超过三位,比如14写成XIV,而非XIIII。(见下方“数码限制”一项。)
- 加线乘千:
- 在罗马数字的上方加上一条横线或者加上下标的Ⅿ,表示将这个数乘以1000,即是原数的1000倍。
- 同理,如果上方有两条横线,即是原数的1000000({\displaystyle 1000^{2}}
)倍。
- 数码限制:
- 同一数码最多只能连续出现三次,如40不可表示为XXXX,而要表示为XL。
方案一
从根据红色标红的规则,我们知道在个十百千每一位上的数值肯定是只与对应位上的表达形式有关,而不会牵扯到前一位或后一位上。eg:在十位的表达上有X、XX、XXX、XL、L、LX、LXX、LXXX、XC,而个位和百位对应的表达也都有对应的,完全不会影响到十位上对应的表达。所以,只要整数的十位数值为6,则对应表达式一定是千位+LX+各位。
所以,就是直接列举出个十百千每一位的表现形式,然后我们计算每一位的数值,用对应的字符串去填充就可以了,特殊的一点事罗马数中没有数值0,所以我们给其对应的为空字符串表示。所以有:
【罗马数字】
个位上的0~9: {"","I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
十位上的0~9: {"","X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
百位上的0~9: {"","C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
千位上的0~3: {"","M", "MM", "MMM"}.
所以,代码如下:
public String intToRoman(int num) {
String[][] roman = {
{ "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX" },
{ "", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC" },
{ "", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM" },
{ "", "M", "MM", "MMM" } };
String res = "";
int digit = 0;
while (num != 0) {
int remain = num % 10;
res = roman[digit][remain] + res;
digit++;
num /= 10;
}
return res;
}
方案二
根据上面蓝色标注的部分,我们可以知道,在减数的时候有特定的规律,就是只能减1位且不能跨越一个位数,同时只限于I X C。像上面那个例子,99 不能用IC(100-1)表示,是因为如果一个数字超过90(或等于90),其罗马数字的表示就必须包含一个XC(100-10)。
同理,对I X C都适用这个原则。
这个判断,要从最大往下找,如果一个数字是5,那么他就是属于大于等于5,罗马数字包含V,而无需写成IIIII。所以,可以写成递归的方式,代码可以写成如下(代码源自http://www.cnblogs.com/springfor/p/3886459.html):
public String intToRoman(int num) {
if(num>=1000) return "M"+intToRoman(num-1000);
if(num>=900) return "CM"+intToRoman(num-900);
if(num>=500) return "D"+intToRoman(num-500);
if(num>=400) return "CD"+intToRoman(num-400);
if(num>=100) return "C"+intToRoman(num-100);
if(num>=90) return "XC"+intToRoman(num-90);
if(num>=50) return "L"+intToRoman(num-50);
if(num>=40) return "XL"+intToRoman(num-40);
if(num>=10) return "X"+intToRoman(num-10);
if(num>=9) return "IX"+intToRoman(num-9);
if(num>=5) return "V"+intToRoman(num-5);
if(num>=4) return "IV"+intToRoman(num-4);
if(num>=1) return "I"+intToRoman(num-1);
return "";
}
非递归方式如下:
public String intToRoman(int num) {
String str = "";
String [] symbol = {"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
int [] value = {1000,900,500,400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
for(int i=0;num!=0;i++){
while(num >= value[i]){
num -= value[i];
str += symbol[i];
}
}
return str;
}
No.012 Integer to Roman的更多相关文章
- LeetCode--No.012 Integer to Roman
12. Integer to Roman Total Accepted: 71315 Total Submissions: 176625 Difficulty: Medium Given an int ...
- 【JAVA、C++】LeetCode 012 Integer to Roman
Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 t ...
- 【LeetCode】012. Integer to Roman
Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 t ...
- 012 Integer to Roman 整数转换成罗马数字
给定一个整数,将其转为罗马数字.输入保证在 1 到 3999 之间. 详见:https://leetcode.com/problems/integer-to-roman/description/ cl ...
- [Leetcode]012. Integer to Roman
public class Solution { public String intToRoman(int num) { String M[] = {"", "M" ...
- 《LeetBook》leetcode题解(12):Integer to Roman[M]
我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...
- 【LeetCode】Roman to Integer & Integer to Roman
Roman to Integer Given a roman numeral, convert it to an integer. Input is guaranteed to be within t ...
- 【leetcode】Integer to Roman
Integer to Roman Given an integer, convert it to a roman numeral. Input is guaranteed to be within t ...
- 【leetcode】Integer to Roman & Roman to Integer(easy)
Roman to Integer Given a roman numeral, convert it to an integer. Input is guaranteed to be within t ...
随机推荐
- 【MySQL】unique列插入重复值解决方案
当在一个UNIQUE键上插入包含重复值的记录时,我们可以控制MySQL如何处理这种情况:使用IGNORE关键字或者ON DUPLICATE KEY UPDATE子句跳过INSERT.中断操作或者更新旧 ...
- PLSQL_Oracle簇表和簇表管理Index clustered tables(案例)
2012-06-08 Created By BaoXinjian
- Java爬虫搜索原理实现
permike 原文 Java爬虫搜索原理实现 没事做,又研究了一下爬虫搜索,两三天时间总算是把原理闹的差不多了,基本实现了爬虫搜索的原理,本次实现还是俩程序,分别是按广度优先和深度优先完成的,广度优 ...
- ADO.NET(完整修改和查询、实体类,数据访问类)
一.完整修改和查询 在编写c#语句时需考虑到用户体验,例如在编写修改语句时,需要考虑到输入的内容在数据库中是否能够找到. 中间变量运用. 1.先查 2.执行操作 完整修改语句: bool has = ...
- Axis2的下载和安装
Axis2是一套崭新的WebService引擎,该版本是对Axis1.x重新设计的产物.Axis2不仅支持SOAP1.1和SOAP1.2,还集成了非常流行的REST WebService,同时还支持S ...
- linux挂载U盘(转载)
一.Linux挂载U盘:1.插入u盘到计算机,如果目前只插入了一个u盘而且你的硬盘不是scsi的硬盘接口的话,那它的硬件名称为:sda1.2.在mnt目录下先建立一个usb的目录(如:[root@lo ...
- tony_linux下网站压力测试工具webbench
webbench最多可以模拟3万个并发连接去测试网站的负载能力,个人感觉要比Apache自带的ab压力测试工具好,安装使用也特别方便. 1.适用系统:Linux 2.编译安装:wget http:// ...
- I/O地址映射
几乎每一种外设都是通过读写设备上的寄存器来进行的,通常包括控制寄存器.状态寄存器和数据寄存器三大类,外设的寄存器通常被连续地编址.根据CPU体系结构的不同,CPU对IO端口的编址方式有两种: (1)I ...
- 判断Windows操作系统的版本
private void Form1_Load(object sender, EventArgs e) { if (!IsWin7()) { Application.Exit(); } } bool ...
- MSSQL中的随机函数
随机函数:rand()在查询分析器中执行:select rand(),可以看到结果会是类似于这样的随机小数:0.36361513486289558,像这样的小数在实际应用中用得不多,一般要取随机数都会 ...