本题主要难点有两部分:
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<Product> products;//商品信息 10 static ArrayList<Coin> 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<Product>(); 71 coins = new ArrayList<Coin>(); 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<Integer, Integer> weightAndIndexMap = new HashMap<Integer, Integer>(); 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<String, Integer> productNameAndIndexMap = new HashMap<String, Integer>(); 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<Integer> coinStack = new Stack<Integer>(); 225 Stack<Integer> changeStack = new Stack<Integer>(); 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 }