LeetCode 算法刷题(12)

12. Integer to Roman

Given an integer, convert it to a roman numeral.

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

罗马数字

罗马数字是古罗马时期的计数系统,也是最早的数字表示方式,多用于钟表、日历和章节编号。一般认为,罗马数字只用来计数而不作演算。像II,IV,VII,这些都是常见的罗马数字。

构造规则

罗马数字通过7个不同字母的重复或组合,能够表示出所有正整数(罗马数字中没有0)。

  • I   =  1
  • V  =  5
  • X  =  10
  • L  =   50
  • C  =  100
  • D  =  500
  • M =  1000

1、字母是可以叠加的。

如I 表示 1,II 表示 2,III 表示 3。VI 表示 6(V=5,I=1,VI即V+I,等于6),VII 表示 7,VIII 表示 8。

2、表示为5的倍数的字母(V,L,D)不得重复。其余字母(I,X,C,M)至多可以重复3次。

(1)  如10应该表示为X,而不能是VV。再如十五应该表示为XV,而不是VVV。

(2)如4不能表示为IIII,而应该利用下一个最大的含五字符进行减操作得到,表示为IV(根据规则3,高位的I表示1,低位的V表示5,高位小于低位,因此用低位减去高位,5-1=4)。类似的,9不能表示为XIIII,因为I重复了4次。而要把它表示成10-1的形式,即IX。

3、罗马数字一般从高位到低位书写,从左向右阅读。若位于高位的数较大,则用高位的数加上低位的数;若位于高位的数较小,则用低位的数减去高位的数。

如CD和DC分别表示400和600。CD中,C在高位,它表示的数字是100,D在低位,它表示的数字是500,高位数字小于低位数字,因此用低位的D(500)减去高位的C(100),得出CD表示400;而在DC中,D在高位,数字为500,C在低位,数字为100,高位数字大于低位数字,因此高位加上低位,500+100,得出DC为600。

4、低位减去高位不能跨越一个位数且高位的数只能是I,X,C(即只能减1,减10,减100)。

(1)如99不能表示成100-1,即IC。因为C表示的100和I表示的1之间超过了一个位数。99应该表示成(100-10)+(10-1),即XCIX。

(2)如45不能表示成50-5,因为50-5要写成VL,而低位减高位,高位的数只能是I,X,C,显然V不在此列。所以45只能写成(50-10)+ 5的形式,即XLV。

5、在罗马数字的上方加上一条横线或者加上下标的Ⅿ,表示将这个数乘以1000。同理,两条横线则是乘以1000000。

只要理解了以上5条规则,就能在罗马数字和阿拉伯数字之间进行任意的转换了。最后附上罗马数字对照表:

public String intToRoman(int num) {

        String result = "";
        int[] nums = {1,5,10,50,100,500,1000};
        char[] chars = {'I','V','X','L','C','D','M'};
        int index = nums.length-1;
        int height = 0 ;
        while(num>0&&index>=0){
            height = num/nums[index];
            if(height == 0 ){
                index --;
            }else if((height ==2||height==3)&&(nums[index]!='V'||nums[index]!='L'||nums[index]!='D')){

                for(int i=0; i<height; i++){
                    result = result + chars[index];
                }

                if(index-1<0){
                    break;
                }else{
                    num = num%nums[index--];
                }

            }else{
                if(height==1){

                    //判断下一位的情况 60 70 80
                    int newnum = num%nums[index];
                    if(index-1>=0&&(newnum/nums[index-1]==0||newnum/nums[index-1]==1||((newnum/nums[index-1]==2||newnum/nums[index-1]==3)&&(nums[index]!=5||nums[index]!=50||nums[index]!=500)))){
                        result = result + chars[index];
                        num = num%nums[index--];
                        continue;
                    }

                    if(num==1){
                        result = result + chars[index];
                        break;
                    }

                }

                if((index+1<nums.length&&index-1>=0)&&(nums[index+1]-num<=nums[index-1])){
                    //超过一个位数
                    if(nums[index+1]==1||nums[index+1]==10||nums[index+1]==100||nums[index+1]==1000){
                        //查看高位,如果高位是I,X,C可以接受低位-高位
                        result = result + chars[index-1] + chars[index+1];
                        num = num%nums[index-1];
                        index--;
                    }else{
                        result = result + chars[index] + chars[index+1];
                        num = num%nums[index--];
                    }
                }else{
                    //没有超过一个位数
                    if(index==0){
                        result = result + chars[index]+chars[index+1];
                        break;
                    }else{
                        result = result + chars[index]+chars[index+1];

                        num = num%nums[index-1];
                        index--;
                    }

                }

            }





        }
        System.out.println(result);
        return result;
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值