将整数转换为罗马数字 - Java

2022-08-31 13:23:54

这是我遇到的家庭作业。

我需要使用一种方法制作一个整数到罗马数字转换器。稍后,我必须使用该程序以罗马数字写出1到3999,因此硬编码就出来了。我下面的代码非常简陋;它是一个基本的I / O循环,可以在使用我们在类中制作的软件包时退出。getIntegerFromUser

有没有办法将值分配给字符串,然后在调用该方法时将它们加在一起?

更新:我从我的教授那里得到了一些伪代码来帮助我,虽然我理解他想说什么,但我在s方面遇到了一些麻烦。我是否需要很多很多的语句,以便我的转换器能够正确处理罗马数字格式,或者是否有一种方法可以更有效地执行此操作?我已经更新了我的代码以反映我的占位符方法。ifif

更新(2012 年 10 月 28 日):我让它工作了。以下是我最终使用的内容:

public static String IntegerToRomanNumeral(int input) {
    if (input < 1 || input > 3999)
        return "Invalid Roman Number Value";
    String s = "";
    while (input >= 1000) {
        s += "M";
        input -= 1000;        }
    while (input >= 900) {
        s += "CM";
        input -= 900;
    }
    while (input >= 500) {
        s += "D";
        input -= 500;
    }
    while (input >= 400) {
        s += "CD";
        input -= 400;
    }
    while (input >= 100) {
        s += "C";
        input -= 100;
    }
    while (input >= 90) {
        s += "XC";
        input -= 90;
    }
    while (input >= 50) {
        s += "L";
        input -= 50;
    }
    while (input >= 40) {
        s += "XL";
        input -= 40;
    }
    while (input >= 10) {
        s += "X";
        input -= 10;
    }
    while (input >= 9) {
        s += "IX";
        input -= 9;
    }
    while (input >= 5) {
        s += "V";
        input -= 5;
    }
    while (input >= 4) {
        s += "IV";
        input -= 4;
    }
    while (input >= 1) {
        s += "I";
        input -= 1;
    }    
    return s;
}

答案 1

使用 Java TreeMap 和递归的紧凑实现:

import java.util.TreeMap;

public class RomanNumber {

    private final static TreeMap<Integer, String> map = new TreeMap<Integer, String>();

    static {

        map.put(1000, "M");
        map.put(900, "CM");
        map.put(500, "D");
        map.put(400, "CD");
        map.put(100, "C");
        map.put(90, "XC");
        map.put(50, "L");
        map.put(40, "XL");
        map.put(10, "X");
        map.put(9, "IX");
        map.put(5, "V");
        map.put(4, "IV");
        map.put(1, "I");

    }

    public final static String toRoman(int number) {
        int l =  map.floorKey(number);
        if ( number == l ) {
            return map.get(number);
        }
        return map.get(l) + toRoman(number-l);
    }

}

测试:

public void testRomanConversion() {

    for (int i = 1; i<= 100; i++) {
        System.out.println(i+"\t =\t "+RomanNumber.toRoman(i));
    }

}

答案 2

实际上,还有另一种方式来看待这个问题,不是作为一个数字问题,而是一个一元问题,从罗马数字的基本字符“I”开始。因此,我们仅用 I 表示数字,然后替换罗马字符的升序值中的字符。

public String getRomanNumber(int number) {
    return join("", nCopies(number, "I"))
            .replace("IIIII", "V")
            .replace("IIII", "IV")
            .replace("VV", "X")
            .replace("VIV", "IX")
            .replace("XXXXX", "L")
            .replace("XXXX", "XL")
            .replace("LL", "C")
            .replace("LXL", "XC")
            .replace("CCCCC", "D")
            .replace("CCCC", "CD")
            .replace("DD", "M")
            .replace("DCD", "CM");
}

我特别喜欢这种解决这个问题的方法,而不是使用大量的if和while循环,或表查找。当你把问题而不是一个数字问题考虑时,它实际上也是一个退出的直观解决方案。