java - While Loop 不更新 TreeMap 的值
问题描述
我目前正在尝试编写一个将整数从 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();
}
解决方案
问题是您正在遍历TreeMap
其自然键顺序。
因此,考虑一个像这样的最小罗马地图,具有以下键顺序:
key = 1
,value = "I"
key = 5
,value = "V"
使用输入6
会发生以下情况:
第一key = 1
,第一value = "I"
,number = 6
在你的while
循环中,你有,所以通过 key6 >= 1 => true
追加"I"
和减少。6
1
然后重复 for 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));
推荐阅读
- windows-server - 如何从命令/powershell 执行 WindowsServer2019 的 setup.exe 安装程序?
- graphics - ImageMagick -fuzz OR 重心裁剪与适合可扩展纵横比框的东西
- javascript - 与 Axios 反应无法将数组映射到列表
- mongodb - 想知道 MongoDB 与 Firebase 和 Flutter 的安全性
- ios - Vue 站点的 Webpack url-loader PDF 数据 URI 链接在 iOS 14 中停止工作
- java - Java EntityManager 抛出 NullPointerException
- c++ - 没有匹配的函数调用...(使用模板和指针)
- c# - 如何在测试 ASP.NET Core 应用程序时使用 EF Core 使用 InMemory 数据库将数据播种到 DbContext?
- python - 如何在绘图内放大
- vue.js - 如何使用带有数组长度的 v-if