本题主要难点有两部分:

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 + "]";
} }

华为OJ之自动售货系统的更多相关文章

  1. 语言模拟ATM自动取款机系统

    C语言实验报告       题目名称:C语言模拟ATM自动取款机系统 C语言模拟实现ATM自动取款机功能:输入密码,余额查询,取款,存款,转账,修改密码,退出功能: 代码实现的功能: 账号及密码输入: ...

  2. 艺萌文件上传下载及自动更新系统(基于networkComms开源TCP通信框架)

    1.艺萌文件上传下载及自动更新系统,基于Winform技术,采用CS架构,开发工具为vs2010,.net2.0版本(可以很容易升级为3.5和4.0版本)开发语言c#. 本系统主要帮助客户学习基于TC ...

  3. 自动升级系统OAUS的设计与实现(续) (附最新源码)

    (最新OAUS版本请参见:自动升级系统的设计与实现(续2) -- 增加断点续传功能) 一.缘起 自从 自动升级系统的设计与实现(源码) 发布以后,收到了很多使用者的反馈,其中最多的要求就是希望OAUS ...

  4. 华为OJ:火车进站

    火车进站 给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号.要求以字典序排序输出火车出站的序列号. 输入描述: 有多组测试用例, ...

  5. 京东商城招聘自动调价系统架构师 T4级别

    岗位级别:T4 岗位职责: 1.负责自动调价系统的架构设计 2.负责自动调价的预测.相关性算法设计 3.核心代码编写,代码review 任职要求: 1.熟悉数据挖掘.机器学习理论和算法 2.熟悉海量数 ...

  6. 在华为oj的两个月

    一次偶然的机会,我接触到华为oj平台(http://career-oj.huawei.com/exam/camLogin.jsp),当时的心情很是兴奋,于是立马注册开通,然后迫不及待地上去做题.刚开始 ...

  7. LINUX通过PXE自动部署系统

    原理介绍 TFTP(Trivial File Transfer Protocol,简单文件传输协议)是TCP/IP 协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂.开销不大的 ...

  8. 配置NTP网络时间自动校对系统时间和创建备份文件

    1 案例1:配置用户和组账号 1.1 问题 本例要求创建下列用户.组以及组的成员关系: 新建用户 alex,其用户ID为3456,密码是flectrag 创建一个名为 adminuser 的组 创建一 ...

  9. 自动驾驶系统 bfs

    一家科技公司有一块试验地用于测试自动驾驶系统.试验地由n×m个格子组成,从上到下依次编号为第1到n行,从左到右依次编号为第1到m列.试验车位于其中的某个格子上,每次自动驾驶系统可以控制汽车往上下左右移 ...

随机推荐

  1. Java IO流之内存流

    内存流 1)内存流主要用来操作内存 2)分类 ByteArrayInputStream 主要完成将内容从内存读入程序之中 ByteArrayOutputStream 主要是将数据写入到内存中. 3)输 ...

  2. Python之正则表达式(re模块)

    本节内容 re模块介绍 使用re模块的步骤 re模块简单应用示例 关于匹配对象的说明 说说正则表达式字符串前的r前缀 re模块综合应用实例 正则表达式(Regluar Expressions)又称规则 ...

  3. Python一键升级所有 模块/package

    import os,time allPackage=os.popen('pip list') allPackage=allPackage.read() allPackage=allPackage.sp ...

  4. 基于angular实现模拟微信小程序swiper组件

    这段时间的主业是完成一个家政类小程序,终于是过审核发布了.不得不说微信的这个小程序生态还是颇有想法的,抛开他现有的一些问题不说,其提供的组件系统乍一看还是蛮酷的.比如其提供的一个叫swiper的视图组 ...

  5. 【锋利的jQuery】中全局事件ajaxStart、ajaxStop不执行

    最近一直都在研究[锋利的jQuery],确实是一本好书,受益匪浅.但由于技术发展及版本更新等原因,里面还是有些坑需要踩的. 比如:第六章七节中提到的全局事件ajaxStart.ajaxStop照着案例 ...

  6. Android 图片加载框架Glide4.0源码完全解析(一)

    写在之前 上一篇博文写的是Picasso基本使用和源码完全解析,Picasso的源码阅读起来还是很顺畅的,然后就想到Glide框架,网上大家也都推荐使用这个框架用来加载图片,正好我目前的写作目标也是分 ...

  7. jquery的几个国内CDN加速节点

    分享几个jquery的几个国内国外的CDN加速节点,方便广大的开发设计者调用和节约空间,官网的总是最新版本的jquery所以不用去担心版本更新问题,其他加速节点可能不会在更新版本,所以取舍问题自己决定 ...

  8. 关于MATLAB处理大数据坐标文件2017622

    今天新提交了一次数据,总量达到10337个,本以为成绩会突飞猛进,没想到还是不如从前 但是已经找到人工鼠标轨迹的程序,有待完善,接下来兵分四路:找特征.决策树.完善人工轨迹程序,使其可以将生成的数据自 ...

  9. css的各种选择器

    一.基本选择器 1. * 通用元素选择器,匹配任何元素 2. E 标签选择器,匹配所有使用E标签的元素 3. .info class选择器,匹配所有class属性中包含info的元素 4. #foot ...

  10. Latex: 插入数学公式

    write equations align equations to left To only align one equation, you can \begin{flalign} &\te ...