[Leetcode]Integer与Roman的相互转换

罗马数字Roman表示方法:

罗马字符对应的阿拉伯数字:

I = 1;
V = 5;
X = 10;
L = 50;
C = 100;
D = 500;

M = 1000;

计数规则为:

1. 相同字符连在一起所标示的数为这些字符代表数字之和,如III=3。

2. 较小字符在较大字符右边,表示数字为所有字符相加,如VI=6。

3. 较小字符在较大字符左边,所标示的数为大数减小树,如IV=4。

4. 相同连续字符不能重复超过三次。

仅限于3999以内数字


Roman to Integer:

将罗马字符转换成阿拉伯数字比较简单,用两个引用记录前后两个罗马字符。如果前面的比后面的大,则将其转换为数字后依次相加。如果后面的数字比前面的大,在已有数字基础上减去两倍前面的数,再加上后面的数。算法仅需O(n)复杂度。代码如下:

public class Solution {
    private int charToInt(char c) {
        //将罗马字符转换为阿拉伯数字
            int digit = 0; 
            
            switch(c) {
                case 'I':
                    digit = 1;
                    break;
                case 'V':
                    digit = 5;
                    break;
                case 'X':
                    digit = 10;
                    break;
                case 'L':
                    digit = 50;
                    break;
                case 'C':
                    digit = 100;
                    break;
                case 'D':
                    digit = 500;
                    break;
                case 'M':
                    digit = 1000;
                    break;
            }
            
            return digit;
    }
    
    public int romanToInt(String s) {
        int i, pre, cur, total;//pre用来记录前面的数,cur用来记录当前遍历到的数
        total = charToInt(s.charAt(0));
        
        for (i = 1; i < s.length(); i++) {
            pre = charToInt(s.charAt(i - 1));
            cur = charToInt(s.charAt(i));
            
            if (cur <= pre) {
                //前数大于后数,直接相加
                total += cur;
            } else {
                //前数小于后数,先减去两倍前数,再加上后数
                total = total - 2*pre + cur;
            }
        }
        
        return total;
    }
}

Integer to Roman:

阿拉伯数字到罗马字符的转换比其逆过程略微复杂,首先必须掌握罗马字符的一般规律。
用罗马字符表示各个数位时如下:
个位0~9:I II III IV V VI VII VIII IX.
十位0~9:X XX XXX XL L LX LXX LXXX XC。
百位,千位以此类推。

所以在每一位上,都是由三个罗马字符组成的。
个位:I V X
十位:X L C
百位:C D M

因此可以根据不同数位来进行转换,具体代码如下:
public class Solution {
    private void appendNumberToRoman(int digit, char[] symbol, int i, StringBuffer res) {
        //辅助函数,用来判断在某一位上应该用何种字符表示
		if (digit == 0) {
			return;
		} else if (digit <= 3) {
			for (;digit > 0; digit -= 1) {
				res.append(symbol[i]);
			}
		} else if (digit == 4) {
			res.append(symbol[i]);
			res.append(symbol[i + 1]);
		} else if (digit <= 8) {
			res.append(symbol[i + 1]);
			for (digit = digit - 5; digit > 0; digit -= 1) {
				res.append(symbol[i]);
			}
		} else {
			res.append(symbol[i]);
			res.append(symbol[i + 2]);
		}
	}
	
    public String intToRoman(int num) {
    	char[] symbol = {'I', 'V', 'X', 'L', 'C', 'D', 'M'};//罗马字符符号表
    	StringBuffer res = new StringBuffer("");//创建一个StringBuffer对象,用来传递进辅助函数。为何不用String,原因见下文链接。
    	int scale = 1000;
    	
    	for (int i = 6; i >= 0; i -= 2) {
    		int digit = num / scale;//digit为每一位数字,从千位开始
    		appendNumberToRoman(digit, symbol, i, res);
    		num = num % scale;
    		scale /= 10;
    	}
    	return res.toString();
    }
}

在此程序中,由于使用Java,没有指针概念,所以在传递值还是引用res的问题上做了一些研究。
在Java中,所有primitive类型变量以及String变量,在传递进入函数时用的是值而不是引用。而一般object对象传入的是一份对象引用的拷贝,利用该拷贝可以对对象进行操作。如果在函数中改变了该拷贝的引用(即函数的形参),不会影响其外部函数的引用。详细举例与说明见此链接: http://6924918.blog.51cto.com/6914918/1283761


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值