您的位置:首页 > 其它

华为OJ之自动售货系统

2017-07-22 20:19 48 查看

本题主要难点有两部分:

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

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

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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Scanner;
import java.util.Stack;

public class VendingSystem {

static ArrayList<Product> products;//商品信息
static ArrayList<Coin> coins;//币盒信息
static int balance;//余额

public static void main(String[] args) {
String orders = getParas();
String[] orderArray = orders.split(";");
handleOrder(orderArray);
}

/*
* 处理接收到的命令
*/
public static void handleOrder(String[] orderArray) {
char operation = ' ';
for (String order : orderArray) {
operation = order.charAt(0);
switch (operation) {
//初始化
case 'r':
initialize(order);
break;
//投币
case 'p':
dropCoin(order);
break;
//购买
case 'b':
buy(order);
break;
//退币
case 'c':
change(order);
break;
//查询
case 'q':
query(order);
break;
default:
break;
}
}
}

/*
* 获取输入命令
*/
public static String getParas() {
Scanner reader = new Scanner(System.in);
String orders = reader.nextLine();
reader.close();
return orders;
}

/*
* 初始化商品个数和钱币个数
*/
public static void initialize(String paras) {
int[] productPrice = {2, 3, 4, 5, 8, 6};
int[] coinValue = {1, 2, 5, 10};
String[] initializationData = paras.split(" ");
products = new ArrayList<Product>();
coins = new ArrayList<Coin>();
String[] productNum = initializationData[1].split("-");
for (int i = 0; i < productNum.length; i ++) {
products.add(new Product(("A" + (i + 1)), productPrice[i], Integer.parseInt(productNum[i])));
}
String[] coinNum = initializationData[2].split("-");
for (int j = 0; j < coinNum.length; j ++) {
coins.add(new Coin((coinValue[j] + " yuan coin"), coinValue[j], Integer.parseInt(coinNum[j])));
}
System.out.println("S001:Initialization is successful");
}

/*
* 处理查询请求
*/
public static void query(String order) {
String[] queryPara = order.split(" ");
if (queryPara.length < 2 || (!queryPara[1].equals("0") && !queryPara[1].equals("1"))) {
System.out.println("E010:Parameter error");
return;
}
if (queryPara[1].equals("0")) {
int weight = 0;//weight用来保存每件商品的排序优先级,越大则优先级越高,注意weight是不会重复的
HashMap<Integer, Integer> weightAndIndexMap = new HashMap<Integer, Integer>();
int[] weights = new int[products.size()];
for (int i = 0; i < products.size(); i ++) {
weight = products.get(i).getNum() * 10 - i;
weights[i] = weight;
weightAndIndexMap.put(weight, i);
}
Arrays.sort(weights);
Product tempProduct = null;
for (int i = weights.length - 1; i >= 0; i --) {
tempProduct = products.get(weightAndIndexMap.get(weights[i]));
System.out.println(tempProduct.getName() + " " + tempProduct.getPrice() + " " + tempProduct.getNum());
}

} else {
for (Coin coin : coins) {
System.out.println(coin.name + " number=" + coin.num);
}
}
}

/*
* 处理投币
*/
public static void dropCoin(String order) {
String[] dropPara = order.split(" ");
//注意题目给的稍微有点问题,这里的判断确认参数为正整数
//投币金额
int dropValue = Integer.parseInt(dropPara[1]);
if (dropValue != 1 && dropValue != 2 && dropValue != 5 && dropValue != 10 && dropValue < 10) {
System.out.println("E002:Denomination error");
} else {
//钱盒中1, 2硬币总额
int temp = coins.get(0).getNum() * coins.get(0).getValue() +
coins.get(1).getNum() * coins.get(1).getValue();
if (temp < dropValue && dropValue != 1 && dropValue != 2) {
System.out.println("E003:Change is not enough, pay fail");
return;
}
if (Integer.parseInt(dropPara[1]) > 10) {
System.out.println("E004:Pay the balance is beyond the scope biggest");
return;
}
boolean isProductEmpty = true;
for (Product product : products) {
if (product.getNum() > 0) {
isProductEmpty = false;
break;
}
}
if (isProductEmpty) {
System.out.println("E005:All the goods sold out");
return;
}

switch (dropValue) {
case 1:
coins.get(0).setNum(coins.get(0).getNum() + 1);
break;
case 2:
coins.get(1).setNum(coins.get(1).getNum() + 1);
break;
case 5:
coins.get(2).setNum(coins.get(2).getNum() + 1);
break;
case 10:
coins.get(3).setNum(coins.get(3).getNum() + 1);
break;
default:
break;
}
balance += dropValue;
System.out.println("S002:Pay success,balance=" + balance);
}
}

/*
* 处理购买命令
*/
public static void buy(String order) {
String[] buyPara = order.split(" ");
HashMap<String, Integer> productNameAndIndexMap = new HashMap<String, Integer>();
for (int i = 0; i < products.size(); i ++) {
productNameAndIndexMap.put(products.get(i).getName(), i);
}
String productToBuy = buyPara[1];
if (productToBuy.equals("A1") || productToBuy.equals("A2") ||
productToBuy.equals("A3") ||productToBuy.equals("A4") ||
productToBuy.equals("A5") ||productToBuy.equals("A6")) {
Product tempProduct = products.get(productNameAndIndexMap.get(productToBuy));
if (tempProduct.getNum() == 0) {
System.out.println("E007:The goods sold out");
return;
}
if (tempProduct.getPrice() > balance) {
System.out.println("E008:Lack of balance");
return;
}
tempProduct.setNum(tempProduct.getNum() - 1);
balance -= tempProduct.getPrice();
System.out.println("S003:Buy success,balance=" + balance);
} else {
System.out.println("E006:Goods does not exist");
}
}

/*
* 退钱找零
*/
public static void change(String order) {
if (balance == 0) {
System.out.println("E009:Work failure");
return;
}
int[] coinNums = new int[coins.size()];
for (int i = 0; i < coins.size(); i ++) {
coinNums[i] = coins.get(i).getNum();
}
findChange(coinNums, balance);
}

/*
* 退币方法
*/
public static boolean findChange(int[] coinNums, int countToChange) {
if (countToChange < 1) {
return false;
}
int originalCount = countToChange;
boolean isFound = false;
Stack<Integer> coinStack = new Stack<Integer>();
Stack<Integer> changeStack = new Stack<Integer>();
for (int i = 0; i < coinNums.length; i ++) {
for (int j = 0; j < coinNums.length - i; j ++) {
for (int k = 0; k < coinNums[j]; k ++) {
switch (j) {
case 0:
coinStack.push(1);
break;
case 1:
coinStack.push(2);
break;
case 2:
coinStack.push(5);
break;
case 3:
coinStack.push(10);
break;
default:
break;
}
}
}
while (!coinStack.isEmpty()) {
int tempCoinValue = coinStack.pop();
if (countToChange >= tempCoinValue) {
countToChange -= tempCoinValue;
changeStack.push(tempCoinValue);
}
}
if (countToChange == 0) {
isFound = true;
break;
} else {
countToChange = originalCount;
coinStack.clear();
changeStack.clear();
}
}
if (isFound) {
balance = 0;
int[] changeResult = new int[coinNums.length];
while (!changeStack.isEmpty()) {
switch (changeStack.pop()) {
case 1:
changeResult[0] ++;
break;
case 2:
changeResult[1] ++;
break;
case 5:
changeResult[2] ++;
break;
case 10:
changeResult[3] ++;
break;
default:
break;
}
}
for (int i = 0; i < changeResult.length; i ++) {
coins.get(i).setNum(coins.get(i).getNum() - changeResult[i]);
switch (i) {
case 0:
System.out.println("1 yuan coin number=" + changeResult[i]);
break;
case 1:
System.out.println("2 yuan coin number=" + changeResult[i]);
break;
case 2:
System.out.println("5 yuan coin number=" + changeResult[i]);
break;
case 3:
System.out.println("10 yuan coin number=" + changeResult[i]);
break;
default:
break;
}
}
return true;
} else {
return findChange(coinNums, originalCount - 1);
}
}
}
class Product {

String name;
int price;
int num;

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}

public Product() {

}

public Product(String name, int price, int num) {
super();
this.name = name;
this.price = price;
this.num = num;
}
@Override
public String toString() {
return "Product [name=" + name + ", price=" + price + ", num=" + num + "]";
}

}
class Coin {

String name;
int value;
int num;

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public Coin() {
super();
}
public Coin(String name, int value, int num) {
super();
this.name = name;
this.value = value;
this.num = num;
}
@Override
public String toString() {
return "Coin [name=" + name + ", value=" + value + ", num=" + num + "]";
}

}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: