我有一项任务,我不知道如何解决它的问题。
我不是要求你解决整个问题!所以,一旦看到"赋值",就不要进行投票。
这是数据结构和算法课程,它说使用适当的数据结构解决问题。首先,我将在此处复制作业:
编写一个可以进行更改的Java程序。"您的程序应该使用两个数字作为输入,一个是收取的货币金额,另一个是给定的货币金额。然后它应该返回每种账单和硬币的数量,以作为给定金额和收取金额之间的差异的变化。分配给账单和硬币的值可以基于任何现任或前任政府的货币系统。尝试设计你的程序,以便尽可能多地返回账单和硬币。
如果我理解正确,我们必须编写一个程序,可以用最少的使用量来计算用钞票和硬币偿还的金额。
到目前为止,我们只学习了堆栈,队列和链接列表,但我不知道如何使用其中一种数据结构来解决此分配。
哪种数据结构适合解决此类问题?为什么?
答案 0 :(得分:1)
我会使用地图。例如,75将表示为:
100 -> 0
50 -> 1
20 -> 1
10 -> 0
5 -> 1
...
0.01 ->0
意思是零票据,五十票据之一等等。
答案 1 :(得分:1)
这是一种寻找最佳解决方案的算法。基本上,它会遍历所有可能的面额,寻找最短的变化值列表。
// How many cents in a dollar.
private static final int DOLLARS = 100;
// In cents.
private static final int[] denominations = {
// $100
100 * DOLLARS,
// $50
50 * DOLLARS,
// $20
20 * DOLLARS,
// $10
10 * DOLLARS,
// $5
5 * DOLLARS,
// $2
2 * DOLLARS,
// $1
1 * DOLLARS,
// 50c
50,
// 25c
25,
// 5c
5,
// 1c
1
};
private List<Integer> makeChange(int value) {
// Null means none found so far.
List<Integer> change = null;
System.out.println("Make change for " + value);
// For all denomination.
for (int i : denominations) {
// that is less than the value
if (i <= value) {
// Build a new candidate.
List<Integer> newChange = new LinkedList<>();
// Remember it.
newChange.add(i);
// If we are at zero we're done.
if (i < value) {
// Make change from the remaining value.
List<Integer> theRest = makeChange(value - i);
if (theRest != null) {
// Gode more.
newChange.addAll(theRest);
}
}
// Is it shorter?
if (change == null || newChange.size() < change.size()) {
// Better.
change = newChange;
System.out.println("Better change for " + value + " = " + change);
}
}
}
return change;
}
使用26
这样的低数字来尝试这一点会在合理的时间内给你一个好的结果。大约10美元以上的美元大关,它将会挣扎,因为它必须列举每种安排的所有可能的子安排 - 即使它之前已经看过它们。
如果我们被允许使用Map
,我们可以通过记住之前的最佳计算(称为Memoisation)来改善问题。这个可以处理更大的数字,因为它永远不必重新计算任何数字的最佳变化。
// All the best lists I've seen so far.
Map<Integer, List<Integer>> memory = new HashMap<>();
private List<Integer> makeChangeUsingMap(int value) {
// If we've seen this one before, use it.
if (memory.containsKey(value)) {
return memory.get(value);
}
// Null means none found so far.
List<Integer> change = null;
System.out.println("Make change for " + value);
// For all denomination.
for (int i : denominations) {
// that is less than the value
if (i <= value) {
// Build a new candidate.
List<Integer> newChange = new LinkedList<>();
// Remember it.
newChange.add(i);
// If we are at zero we're done.
if (i < value) {
// Make change from the remaining value.
List<Integer> theRest = makeChangeUsingMap(value - i);
if (theRest != null) {
// Gode more.
newChange.addAll(theRest);
}
}
// Is it shorter?
if (change == null || newChange.size() < change.size()) {
// Better.
change = newChange;
System.out.println("Better change for " + value + " = " + change);
// Remember it.
memory.put(value, change);
}
}
}
return change;
}