Хотя Loop не обновляет значение TreeMap

77
5

В настоящее время я пытаюсь написать программу, которая преобразует целые числа от 0-3999 в Roman Numerals, и у меня есть основа кода правильно, так как, когда я печатаю, например, 6, он производит IIIIII. Тем не менее, я хочу, чтобы он преобразовал в правильную римскую цифру, которая была бы VI. Я чувствую, что что-то не так с моим циклом While, но не может понять, почему Key в моей TreeMap всегда будет 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();

}

спросил(а) 2021-01-19T16:41:41+03:00 6 месяцев назад
1
Решение
77

Проблема в том, что вы перемещаете 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));

ответил(а) 2021-01-19T16:41:41+03:00 6 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема