While循环不更新TreeMap的值

时间:2018-07-15 14:34:57

标签: java while-loop hashmap roman-numerals

我目前正在尝试编写一个将0-3999的整数转换为罗马数字的程序,并且我已经获得了正确的代码基础,例如当我键入例如。 6,产生IIIIII。但是,我希望将其转换为正确的罗马数字,即VI。我感觉我的While循环有问题,但似乎无法弄清楚为什么TreeMap中的Key始终为1,意味着数字始终为I。我的代码有什么问题,以及如何将其更改为给我正确的罗马数字。任何帮助将不胜感激。

    public String generate(int number) {
    // System.out.println("NUMBER: " + number);
    if (number < MinNumber || number > MaxNumber) {
        System.out.println("Number is out of range");
        return null;
    }

    StringBuilder romanToString = new StringBuilder();
    NavigableMap<Integer, String> romanMap = createRomanMap();
    // TreeMap<Integer, String> romanMap = createRomanMap();
    for (Map.Entry<Integer, String> entries : romanMap.entrySet()) {
        Integer key = entries.getKey();
        String value = entries.getValue();

        while (number >= key) {
            number -= key;
            romanToString.append(value);
        }
    }
    System.out.println("Stringbuilder:  " + romanToString.toString());
    return romanToString.toString();

}

1 个答案:

答案 0 :(得分:2)

问题是您正在按其自然键顺序遍历TreeMap

因此考虑这样的最小罗马地图,并具有以下按键顺序:

key = 1value = "I"

key = 5value = "V"

使用输入6会发生以下情况:

key = 1,前value = "I"number = 6

在您的while循环中,您有6 >= 1 => true,因此请附加"I"并通过键6递减1

然后对54321重复此操作,直到while循环不变式被破坏为止。


但是,如果罗马地图的降序排列(即自然顺序的倒序),您将获得预期的行为:

key = 5,前value = "V"number = 6

您现在拥有6 >= 5 => true,因此请附加"V",并通过键6递减5,因此1。 然后1 >= 5 => false,因此移至下一个罗马地图条目。


如何实现?

选项1

使用降序地图视图的条目集:

Map.Entry<Integer, String> entrySet = romanMap.descendingMap().entrySet();

选项2

使用自定义TreeMap来构造Comparator,以更改TreeMap的顺序,例如:

SortedMap<Integer, String> romanMap = new TreeMap<>((int1, int2) -> Integer.compare(int2, int1));