华为OJ之自动售货系统

本题主要难点有两部分:

1,找零算法。如何找零应该是最具技巧性的部分,根据已有的硬币金额分布,对应的解决办法可能会有不同。本题中的1,2,5,10这种情况满足贪心性质,故我们简单的用贪心算法的思想来解决。一般更加通用的是利用动态规划或者穷举,这个后面有机会会专门进行讨论。

2,代码业务逻辑。本题所描述的系统已经是一个较为完整的贩卖系统,更多地需要我们从整体上把握代码结构,明白个部分间的关系。如果初始感到无从下手,那么说明在较复杂情况下的编程能力还有欠缺,日后应继续练习。

由于临近入职比较忙,这里简单附上所有的源码,参考其中的注释应不难理解。

  1 import java.util.ArrayList;
  2 import java.util.Arrays;
  3 import java.util.HashMap;
  4 import java.util.Scanner;
  5 import java.util.Stack;
  6 
  7 public class VendingSystem {
  8     
  9     static ArrayList products;//商品信息
 10     static ArrayList coins;//币盒信息
 11     static int balance;//余额
 12     
 13     public static void main(String[] args) {
 14         String orders = getParas();
 15         String[] orderArray = orders.split(";");
 16         handleOrder(orderArray);
 17     }
 18     
 19     /*
 20      * 处理接收到的命令
 21      */
 22     public static void handleOrder(String[] orderArray) {
 23         char operation = ' ';
 24         for (String order : orderArray) {
 25             operation = order.charAt(0);
 26             switch (operation) {
 27             //初始化
 28             case 'r':
 29                 initialize(order);
 30                 break;
 31             //投币
 32             case 'p':
 33                 dropCoin(order);
 34                 break;
 35             //购买
 36             case 'b':
 37                 buy(order);
 38                 break;
 39             //退币
 40             case 'c':
 41                 change(order);
 42                 break;
 43             //查询
 44             case 'q':
 45                 query(order);
 46                 break;
 47             default:
 48                 break;
 49             }
 50         }
 51     }
 52     
 53     /*
 54      * 获取输入命令
 55      */
 56     public static String getParas() {
 57         Scanner reader = new Scanner(System.in);
 58         String orders = reader.nextLine();
 59         reader.close();
 60         return orders;
 61     }
 62     
 63     /*
 64      * 初始化商品个数和钱币个数
 65      */
 66     public static void initialize(String paras) {
 67         int[] productPrice = {2, 3, 4, 5, 8, 6};
 68         int[] coinValue = {1, 2, 5, 10};
 69         String[] initializationData = paras.split(" ");
 70         products = new ArrayList();
 71         coins = new ArrayList();
 72         String[] productNum = initializationData[1].split("-");
 73         for (int i = 0; i < productNum.length; i ++) {
 74             products.add(new Product(("A" + (i + 1)), productPrice[i], Integer.parseInt(productNum[i])));
 75         }
 76         String[] coinNum = initializationData[2].split("-");
 77         for (int j = 0; j < coinNum.length; j ++) {
 78             coins.add(new Coin((coinValue[j] + " yuan coin"), coinValue[j], Integer.parseInt(coinNum[j])));
 79         }
 80         System.out.println("S001:Initialization is successful");
 81     }
 82 
 83     /*
 84      * 处理查询请求
 85      */
 86     public static void query(String order) {
 87         String[] queryPara = order.split(" ");
 88         if (queryPara.length < 2 || (!queryPara[1].equals("0") && !queryPara[1].equals("1"))) {
 89             System.out.println("E010:Parameter error");
 90             return;
 91         }
 92         if (queryPara[1].equals("0")) {
 93             int weight = 0;//weight用来保存每件商品的排序优先级,越大则优先级越高,注意weight是不会重复的
 94             HashMap weightAndIndexMap = new HashMap();
 95             int[] weights = new int[products.size()];
 96             for (int i = 0; i < products.size(); i ++) {
 97                 weight = products.get(i).getNum() * 10 - i;
 98                 weights[i] = weight;
 99                 weightAndIndexMap.put(weight, i);
100             }
101             Arrays.sort(weights);
102             Product tempProduct = null;
103             for (int i = weights.length - 1; i >= 0; i --) {
104                 tempProduct = products.get(weightAndIndexMap.get(weights[i]));
105                 System.out.println(tempProduct.getName() + " " + tempProduct.getPrice() + " " + tempProduct.getNum());
106             }
107             
108         } else {
109             for (Coin coin : coins) {
110                 System.out.println(coin.name + " number=" + coin.num);
111             }
112         }
113     }
114     
115     /*
116      * 处理投币
117      */
118     public static void dropCoin(String order) {
119         String[] dropPara = order.split(" ");
120         //注意题目给的稍微有点问题,这里的判断确认参数为正整数
121         //投币金额
122         int dropValue = Integer.parseInt(dropPara[1]);
123         if (dropValue != 1 && dropValue != 2 && dropValue != 5 && dropValue != 10 && dropValue < 10) {
124             System.out.println("E002:Denomination error");
125         } else {
126             //钱盒中1, 2硬币总额
127             int temp = coins.get(0).getNum() * coins.get(0).getValue() +
128                     coins.get(1).getNum() * coins.get(1).getValue();
129             if (temp < dropValue && dropValue != 1 && dropValue != 2) {
130                 System.out.println("E003:Change is not enough, pay fail");
131                 return;
132             }
133             if (Integer.parseInt(dropPara[1]) > 10) {
134                 System.out.println("E004:Pay the balance is beyond the scope biggest");
135                 return;
136             }
137             boolean isProductEmpty = true;
138             for (Product product : products) {
139                 if (product.getNum() > 0) {
140                     isProductEmpty = false;
141                     break;
142                 }
143             }
144             if (isProductEmpty) {
145                 System.out.println("E005:All the goods sold out");
146                 return;
147             }
148             
149             switch (dropValue) {
150             case 1:
151                 coins.get(0).setNum(coins.get(0).getNum() + 1);
152                 break;
153             case 2:
154                 coins.get(1).setNum(coins.get(1).getNum() + 1);
155                 break;
156             case 5:
157                 coins.get(2).setNum(coins.get(2).getNum() + 1);
158                 break;
159             case 10:
160                 coins.get(3).setNum(coins.get(3).getNum() + 1);
161                 break;
162             default:
163                 break;
164             }
165             balance += dropValue;
166             System.out.println("S002:Pay success,balance=" + balance);
167         }
168     }
169     
170     /*
171      * 处理购买命令
172      */
173     public static void buy(String order) {
174         String[] buyPara = order.split(" ");
175         HashMap productNameAndIndexMap = new HashMap();
176         for (int i = 0; i < products.size(); i ++) {
177             productNameAndIndexMap.put(products.get(i).getName(), i);
178         }
179         String productToBuy = buyPara[1];
180         if (productToBuy.equals("A1") || productToBuy.equals("A2") ||
181                 productToBuy.equals("A3") ||productToBuy.equals("A4") ||
182                 productToBuy.equals("A5") ||productToBuy.equals("A6")) {
183             Product tempProduct = products.get(productNameAndIndexMap.get(productToBuy));
184             if (tempProduct.getNum() == 0) {
185                 System.out.println("E007:The goods sold out");
186                 return;
187             }
188             if (tempProduct.getPrice() > balance) {
189                 System.out.println("E008:Lack of balance");
190                 return;
191             }
192             tempProduct.setNum(tempProduct.getNum() - 1);
193             balance -= tempProduct.getPrice();
194             System.out.println("S003:Buy success,balance=" + balance);
195         } else {
196             System.out.println("E006:Goods does not exist");
197         }
198     }
199     
200     /*
201      * 退钱找零
202      */
203     public static void change(String order) {
204         if (balance == 0) {
205             System.out.println("E009:Work failure");
206             return;
207         }
208         int[] coinNums = new int[coins.size()];
209         for (int i = 0; i < coins.size(); i ++) {
210             coinNums[i] = coins.get(i).getNum();
211         }
212         findChange(coinNums, balance);    
213     }
214     
215     /*
216      * 退币方法
217      */
218     public static boolean findChange(int[] coinNums, int countToChange) {
219         if (countToChange < 1) {
220             return false;
221         }
222         int originalCount = countToChange;
223         boolean isFound = false;
224         Stack coinStack = new Stack();
225         Stack changeStack = new Stack();
226         for (int i = 0; i < coinNums.length; i ++) {
227             for (int j = 0; j < coinNums.length - i; j ++) {
228                 for (int k = 0; k < coinNums[j]; k ++) {
229                     switch (j) {
230                     case 0:
231                         coinStack.push(1);
232                         break;
233                     case 1:
234                         coinStack.push(2);
235                         break;
236                     case 2:
237                         coinStack.push(5);
238                         break;
239                     case 3:
240                         coinStack.push(10);
241                         break;
242                     default:
243                         break;
244                     }
245                 }
246             }
247             while (!coinStack.isEmpty()) {
248                 int tempCoinValue = coinStack.pop();
249                 if (countToChange >= tempCoinValue) {
250                     countToChange -= tempCoinValue;
251                     changeStack.push(tempCoinValue);
252                 }
253             }
254             if (countToChange == 0) {
255                 isFound = true;
256                 break;
257             } else {
258                 countToChange = originalCount;
259                 coinStack.clear();
260                 changeStack.clear();
261             }
262         }
263         if (isFound) {
264             balance = 0;
265             int[] changeResult = new int[coinNums.length];
266             while (!changeStack.isEmpty()) {
267                 switch (changeStack.pop()) {
268                 case 1:
269                     changeResult[0] ++;
270                     break;
271                 case 2:
272                     changeResult[1] ++;
273                     break;
274                 case 5:
275                     changeResult[2] ++;
276                     break;
277                 case 10:
278                     changeResult[3] ++;
279                     break;
280                 default:
281                     break;
282                 }
283             }
284             for (int i = 0; i < changeResult.length; i ++) {
285                 coins.get(i).setNum(coins.get(i).getNum() - changeResult[i]);
286                 switch (i) {
287                 case 0:
288                     System.out.println("1 yuan coin number=" + changeResult[i]);
289                     break;
290                 case 1:
291                     System.out.println("2 yuan coin number=" + changeResult[i]);
292                     break;
293                 case 2:
294                     System.out.println("5 yuan coin number=" + changeResult[i]);
295                     break;
296                 case 3:
297                     System.out.println("10 yuan coin number=" + changeResult[i]);
298                     break;
299                 default:
300                     break;
301                 }
302             }
303             return true;
304         } else {
305             return findChange(coinNums, originalCount - 1);
306         }
307     }
308 }
309 class Product {
310     
311     String name;
312     int price;
313     int num;
314     
315     public String getName() {
316         return name;
317     }
318     public void setName(String name) {
319         this.name = name;
320     }
321     public int getPrice() {
322         return price;
323     }
324     public void setPrice(int price) {
325         this.price = price;
326     }
327     public int getNum() {
328         return num;
329     }
330     public void setNum(int num) {
331         this.num = num;
332     }
333     
334     public Product() {
335         
336     }
337     
338     public Product(String name, int price, int num) {
339         super();
340         this.name = name;
341         this.price = price;
342         this.num = num;
343     }
344     @Override
345     public String toString() {
346         return "Product [name=" + name + ", price=" + price + ", num=" + num + "]";
347     }
348     
349     
350 }
351 class Coin {
352     
353     String name;
354     int value;
355     int num;
356     
357     public String getName() {
358         return name;
359     }
360     public void setName(String name) {
361         this.name = name;
362     }
363     public int getValue() {
364         return value;
365     }
366     public void setValue(int value) {
367         this.value = value;
368     }
369     public int getNum() {
370         return num;
371     }
372     public void setNum(int num) {
373         this.num = num;
374     }
375     public Coin() {
376         super();
377     }
378     public Coin(String name, int value, int num) {
379         super();
380         this.name = name;
381         this.value = value;
382         this.num = num;
383     }
384     @Override
385     public String toString() {
386         return "Coin [name=" + name + ", value=" + value + ", num=" + num + "]";
387     }
388     
389     
390 }

 

你可能感兴趣的:(华为OJ之自动售货系统)