罗马数字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