我目前正在尝试编写一个将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();
}
答案 0 :(得分:2)
问题是您正在按其自然键顺序遍历TreeMap
。
因此考虑这样的最小罗马地图,并具有以下按键顺序:
key = 1
,value = "I"
key = 5
,value = "V"
使用输入6
会发生以下情况:
前key = 1
,前value = "I"
,number = 6
在您的while
循环中,您有6 >= 1 => true
,因此请附加"I"
并通过键6
递减1
。
然后对5
,4
,3
,2
,1
重复此操作,直到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));