羅馬數字生成規則:java
羅馬數字共有7個,即Ⅰ(1)、Ⅴ(5)、Ⅹ(10)、Ⅼ(50)、Ⅽ(100)、Ⅾ(500)和Ⅿ(1000)。按照下述的規則能夠表示任意正整數。須要注意的是羅馬數字中沒有「0」,與進位制無關。通常認爲羅馬數字只用來記數,而不做演算。git
基於生成規則的文法:this
* Grammar: * Thous -> M|MM|MMM|e<br> * 1e300 -> C|CC|CCC|e<br> * Hunds -> 1e300|CD|D1e300|CM|e<br> * 1e30 -> X|XX|XXX|e<br> * Tens -> 1e30|XL|L1e30|XC|e<br> * 1e3 -> I|II|III|e<br> * Units -> 1e3|IV|V1e3|IX|e<br> * <p> * Number -> ThousHundsTensUnits * <p> * e:empty
完整的java程序代碼:code
public final class RomanNumberParser { private final char[] chars; private int lookahead; private int arabic; public RomanNumberParser(String romanNumber) { if (romanNumber == null || romanNumber.length() == 0) throw new IllegalArgumentException("IllegalNumber"); this.chars = romanNumber.toCharArray(); this.lookahead = 0; this.arabic = 0; } public static void main(String[] args) { System.out.println(new RomanNumberParser("MDCCCLXXX").parse()); } private void match(char c) { if (chars[lookahead] == c) { lookahead++; } else { throw new IllegalStateException(); } } private void thous() { for (int i = 0; i < 3; i++) { if (lookahead('M')) { match('M'); arabic += 1000; } else break; } } private void hundreds() { digit('C', 'D', 'M', 100); } private void tens() { digit('X', 'L', 'C', 10); } private void units() { digit('I', 'V', 'X', 1); } private boolean lookahead(char c) { return lookahead < chars.length && chars[lookahead] == c; } private void bis(char c, int nc) { match(c); arabic += nc; if (lookahead(c)) bis(c, nc); } private void digit(char c1, char c5, char c10, int nc1) { if (lookahead(c1)) { match(c1); if (lookahead(c1)) { arabic += nc1; bis(c1, nc1); } else if (lookahead(c5)) { match(c5); arabic += 4 * nc1; } else if (lookahead(c10)) { match(c10); arabic += 9 * nc1; } else { arabic += nc1; } } else if (lookahead(c5)) { match(c5); arabic += 5 * nc1; for (int i = 0; i < 3; i++) { if (lookahead(c1)) { match(c1); arabic += nc1; } } } } public int parse() { thous(); hundreds(); tens(); units(); return arabic; } }