public Map<Integer, Integer> withdrawAmount(int expectedAmount) throws NotEnoughMoneyException {
Map<Integer, Integer> withdraw = new HashMap<>(); // мапа, которую будет отдавать клиенту
int sum = 0; // сумма, которую набираем
int ostatok = expectedAmount; // сколько осталось набрать
ArrayList<Integer> arrayList = new ArrayList();
for (Map.Entry<Integer, Integer> pair : denominations.entrySet())
{ arrayList.add(pair.getKey()); } // забрали в лист все купюры
Collections.sort(arrayList); // сделали сортировку
int i = arrayList.size()-1; // начинаем анализ с конца (т.к. сортировка от меньшего к большему)
boolean posibility = false; //показывает, возможно ли набрать данную сумму или нет
while (true) { // первый цикл проверяет возможно ли в целом набрать данную сумму,
//здесь никаких операций с мапой
int current = arrayList.get(i); // взяли старшую купюру
int ammaxcup = denominations.get(current); // взяли количество купюр
int k = ostatok/current; // посмотрели сколько целых купюр вмещается
if(k<ammaxcup) { sum = sum + k*current; } // если у нас есть столько или больше, то берем эти купюры
else { sum = sum + current*ammaxcup; } // если нет, то зибираем все какие есть
ostatok = expectedAmount - sum; // считаем сколько осталось набрать
if (ostatok==0) { ostatok = expectedAmount; i = arrayList.size()-1; sum = 0;
posibility=true; break;} // если набрать удалось, то делаю posibility=true и обнуляю переменные,
//т.к. дальше будет делаться тоже самое, но уже с действиями над мапой
i = i - 1; //идем на следующую купюру
if(i<0) { // если дошли до конца лист и сумма не набралась,
// значит невозможно набрать такую сумму
throw new NotEnoughMoneyException();} }
if(posibility) { while (true) { // все тоже самое, но уже делаю манипуляции надо мапой
int current = arrayList.get(i);
int ammaxcup = denominations.get(current);
int k = ostatok / current;
if (k < ammaxcup) {
sum = sum + k * current;
if (k!=0) {
withdraw.put(current,k);} // положил в мапу купюры
denominations.put(current, ammaxcup - k); //забираю купюры из банкомата
} else {
sum = sum + current * ammaxcup;
withdraw.put(current,ammaxcup);
denominations.remove(current); //забираю купюры из банкомата
}
ostatok = expectedAmount - sum;
if (ostatok == 0) {
System.out.println("Сумма выдана");
break;}
i = i - 1; } }
return withdraw;
}
В общем, валидацию прошло, но код не совсем нравится, т.к. делаю одно и тоже 2 раза + создается много шелухи типа листов и т.д.
Да и в целом - многа букаф.
Есть идеи, что можно укоротить и как сделать код лучше (быстрей и менее прожорливым) ?
Буду благодарен за идеи! ilya
35 уровень
Хочется понять - это законно ?
Обсуждается
Комментарии (9)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Сергеев ВикторMaster
6 января 2018, 19:21
вас преподаватель бил за использование лишних строчек? Отформатируйте код в нормальный вид.
0
ilya
7 января 2018, 02:44
А вас избивали ? Хотите об этом поговорить ?)
Зачем вся эта агрессия, как школьники, чесн слово.
По делу - отредактировал комментарии, если вам так удобней.
0
Стас Пасинков Software Developer в Zipy Master
6 января 2018, 16:54
а что должен делать этот метод? если на словах)
потому что я пока дошел до середины кода - уже забыл что было в начале))
+1
ilya
7 января 2018, 02:35
9 уровень, 15 лекция
10 задание
Метод withdrawAmount должен возвращать минимальное количество банкнот, которыми набирается запрашиваемая сумма.
Используйте Жадный алгоритм (use google).
Если есть несколько вариантов, то использовать тот, в котором максимальное количество банкнот высшего номинала.
Если для суммы 600 результат - три банкноты: 500 + 50 + 50 = 200 + 200 + 200, то выдать первый вариант.
Мы же не можем одни и те же банкноты выдавать несколько раз, поэтому
если мы нашли вариант выдачи денег (п.2.1. успешен), то вычесть все эти банкноты из карты в манипуляторе.
2.3. метод withdrawAmount должен кидать NotEnoughMoneyException, если купюрами невозможно выдать запрашиваемую сумму.
Пример, надо выдать 600.
В манипуляторе есть следующие банкноты:
500 - 2
200 - 2
Результат - данными банкнотами невозможно выдать запрашиваемую сумму. Кинуть исключение.
Не забудьте, что в некоторых случаях картой кидается ConcurrentModificationException.
0
Стас Пасинков Software Developer в Zipy Master
7 января 2018, 03:37
вообще то я просил просто на словах описать что делает ваш метод, но за условие тоже спасибо :)
а не думали после 134й строки (это из вашего вопроса нумерация, в идее могут отличаться номера строк) вставить иф из 11й строки, удалить иф с проверкой посибилити, и потом удалить все с 89й по 113ю? :)
0
ilya
7 января 2018, 03:53
cорян) не так понял.
я тут редактировал код, и сейчас номера строк сбились.
но я там чото 134 строки не видел, тем не менее)
Можно, плз, исходя из нынешнего положения ?
0
Стас Пасинков Software Developer в Zipy Master
7 января 2018, 12:53
я предлагал выкинуть ту часть, где вы проверяете возможность, а оставить только наполнение мапы. и добавить иф, который бы кидал исключение. не уверен, в то ли я место вставил тот иф, но примерно так в общем:
0
ilya
8 января 2018, 01:20
нееее, это первый вариант который приходил в голову, но проблема в том, что Вы из мапы удалите купюры или измените их количество, не зная точно - можно ли набрать данную сумму ( т.к. в банкомате мб купюры только по 200, а Вам нужно только 100). Так что не пройдет. Я думал ввести какую-то временную переменную, которая будет затронутые купюры считать, но это выльется в добавление новой мапы или листа, что не считаю целесообразным. у меня тут, конечно, карусель и все крутится по второму разу, но с старыми переменными и без лишних действий над мапой.
Тем не менее - спасибо за адекватный ответ! Люблю людей, которые могут больше чем просто язвить в интернетах :) мирадобра!
0
Стас Пасинков Software Developer в Zipy Master
8 января 2018, 05:38
я бы сделал копию мапы и ее бы ковырял. не получилось собрать - ну ниче, копия же.
получилось бы - внес изменения в основную мапу и все)
но тут действительно кому как больше нравится :)
0