[LeetCode][12]Integer to Roman解析 int转罗马字符时间复杂度为常数的实现-Java实现

来源:互联网 发布:算法导论第四版答案 编辑:程序博客网 时间:2024/06/11 17:31

Q:

Given an integer, convert it to a roman numeral.

Input is guaranteed to be within the range from 1 to 3999.

A:

俺是真不知道啥是roman,我去查了一下合着是罗马字体,这题目意思也很简单就是说我要输入一个数字可以保证是1~3999但是你要把这个阿拉伯数字转换成罗马数字。

首先我们要清楚罗马数字怎么表示的,罗马数字表示如下:

数字共有七个,即I(1),V(5),X(10),L(50),C(100),D(500),M(1000)。
并且罗马数字有以下规则:
重复数次:一个罗马数字重复几次,就表示这个数的几倍。 右加左减:在一个较大的罗马数字的右边记上一个较小的罗马数字,表示大数字加小数字。在一个较大的数字的左边记上一个较小的罗马数字,表示大数字减小数字。但是,左减不能跨越等级。比如,99不可以用IC表示,用XCIX表示。 加线乘千:在一个罗马数字的上方加上一条横线或者在右下方写M,表示将这个数字乘以1000,即是原数的1000倍。同理,如果上方有两条横线,即是原数的1000000倍。 
上面都是copy来的。
下面我们来仔细研究一下这个题目,无非就是输入的阿拉伯数字a = xI + yV+zX。。。。。。得出x,y,z等的值之后根据规则匹配。我们肯定不会去解这个方程,但是可以肯定的是,他跟阿拉伯数字很像,首先末尾肯定是1~9中间的。加下来就是十位,百位,千位的转化相加了。
我们大概需要以下几种表:
1~9(9个)
10~90(9个)
100~900(9个)
1000~3000(3个)
为什么我们选择对比,因为这样快啊,但是仔细想想,有没有一个公式直接生成呢?
1~3都是1(10、100、1000)叠加的
4~8都是5(50、500)加减1(10、100)得到的
9都是10(100、1000)减掉1(10、100)得到的。
我们也可以用这个规律来运算出来需要转换的数值。
于是我们只需要从尾部开始遍历这个int就好了,具体遍历的方法请看我之前的一篇模仿jdk实现的源码点击打开链接
具体代码如下:

public class IntegertoRoman {public static void main(String[] args){int a = 999;System.out.println(method(a));}private static String method(int i) {// TODO Auto-generated method stubint r =0;int q = 1;int times = 0;String roman ="";while (true) {times ++;q = (i * 52429) >>> 19;//去尾1位,2<<(16+3)=524288 52429/524288约为0.1r = i - ((q << 3) + (q << 1));//r=i-q*10,截出最后一位i=q;switch(times){case 1://个位roman = convertRoman(r, "I", "V", "X");break;case 2://十位roman = convertRoman(r, "X", "L", "C")+roman;break;case 3://百位roman = convertRoman(r, "C", "D", "M")+roman;break;case 4://千位roman = convertRoman(r, "M", "null", "null")+roman;break;}if(q==0)break;}return roman;}/** * 一位罗马数字转化 * @param r 需要转化的罗马数字 * @param one 这一位代表1的罗马字母 * @param five 这一位代表5的罗马字母 * @param ten 这一位代表10的罗马字母 * @return */public static String convertRoman(int r,String one,String five,String ten){String roman ="";if(r==0)return "";else if(0<r&&r<=3){//oneString s = "";for(int k = 0;k<r;k++){s+=one;}roman = roman+s;}else if(3<r&&r<=8){//five+/-oneString s = "";if(r==4){s=one+five;}else {for(int k = 5;k<r;k++){s+=one;}s= five+s;}roman = roman+s;}else if(r == 9){//ten-oneroman = one+ten;}return roman;}
perfect~完美解决

1 0
原创粉丝点击