华为OJ之自动售货系统
本题主要难点有两部分:
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之自动售货系统的更多相关文章
- 语言模拟ATM自动取款机系统
C语言实验报告 题目名称:C语言模拟ATM自动取款机系统 C语言模拟实现ATM自动取款机功能:输入密码,余额查询,取款,存款,转账,修改密码,退出功能: 代码实现的功能: 账号及密码输入: ...
- 艺萌文件上传下载及自动更新系统(基于networkComms开源TCP通信框架)
1.艺萌文件上传下载及自动更新系统,基于Winform技术,采用CS架构,开发工具为vs2010,.net2.0版本(可以很容易升级为3.5和4.0版本)开发语言c#. 本系统主要帮助客户学习基于TC ...
- 自动升级系统OAUS的设计与实现(续) (附最新源码)
(最新OAUS版本请参见:自动升级系统的设计与实现(续2) -- 增加断点续传功能) 一.缘起 自从 自动升级系统的设计与实现(源码) 发布以后,收到了很多使用者的反馈,其中最多的要求就是希望OAUS ...
- 华为OJ:火车进站
火车进站 给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号.要求以字典序排序输出火车出站的序列号. 输入描述: 有多组测试用例, ...
- 京东商城招聘自动调价系统架构师 T4级别
岗位级别:T4 岗位职责: 1.负责自动调价系统的架构设计 2.负责自动调价的预测.相关性算法设计 3.核心代码编写,代码review 任职要求: 1.熟悉数据挖掘.机器学习理论和算法 2.熟悉海量数 ...
- 在华为oj的两个月
一次偶然的机会,我接触到华为oj平台(http://career-oj.huawei.com/exam/camLogin.jsp),当时的心情很是兴奋,于是立马注册开通,然后迫不及待地上去做题.刚开始 ...
- LINUX通过PXE自动部署系统
原理介绍 TFTP(Trivial File Transfer Protocol,简单文件传输协议)是TCP/IP 协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂.开销不大的 ...
- 配置NTP网络时间自动校对系统时间和创建备份文件
1 案例1:配置用户和组账号 1.1 问题 本例要求创建下列用户.组以及组的成员关系: 新建用户 alex,其用户ID为3456,密码是flectrag 创建一个名为 adminuser 的组 创建一 ...
- 自动驾驶系统 bfs
一家科技公司有一块试验地用于测试自动驾驶系统.试验地由n×m个格子组成,从上到下依次编号为第1到n行,从左到右依次编号为第1到m列.试验车位于其中的某个格子上,每次自动驾驶系统可以控制汽车往上下左右移 ...
随机推荐
- 2-SAT算法
参考blog 参考论文 参考论文 题目 & 题解 裸2-SAT poj3683 poj3207 poj3678 poj3648 2-SAT + 二分法 poj2723 poj2749 hdu3 ...
- list与Set、Map区别
1.List,Set都是继承自Collection接口,Map则不是 2.List特点:元素有放入顺序,元素可重复 ,Set特点:元素无放入顺序,元素不可重复,重复元素会覆盖掉,(注意:元素虽然无放入 ...
- Java开发中的23+2种设计模式学习个人笔记(未完待续)
注:个人笔记 一.设计模式分三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模 ...
- wdcp php5.3添加pdo_mysql模块
先查看探针: pdo没有支持mysql.导致了PHpwind以及thinkphp框架的一些运用了pdo进行mysql操作的程序无法运行. php5.3默认是封装了pdo_mysq的.那么就没必要单独下 ...
- PHP漏洞之session会话劫持
本文主要介绍针对PHP网站Session劫持.session劫持是一种比较复杂的攻击方法.大部分互联网上的电脑多存在被攻击的危险.这是一种劫持tcp协议的方法,所以几乎所有的局域网,都存在被劫持可能. ...
- node.js实现简单的登录注册页面
首先需要新建四个文件 一个服务器js 一个保存数据的txt 一个登陆.一个注册页面html 1.注册页面 <!DOCTYPE html> <html lang="en&qu ...
- oracle表的简单操作
版权声明:本文为博主原创文章,转载时请注明原文链接. 1.创建表 ) ) not null,primary key(num)); 创建了一个两个字段的表,num和name,都设置为非空,num设为主键 ...
- [0] 关于IComparable和IComparer接口和Comparer类
关于IComparable和IComparer接口 和 Comparer类 IComparable和ICompareframeworkr接口是.net 中比较对象的标准方式,这两个接口之间的区别如下: ...
- 跨域CORS
一.跨域CORS是什么 当一个资源从与该资源本身所在的服务器的域或端口不同的域或不同的端口请求一个资源时,浏览器会发起一个跨域 HTTP 请求.出于安全考虑,浏览器会限制从脚本内发起的跨域HTTP请求 ...
- java web项目中 读取properties 路径的问题
可以先获取项目的classPath String classPath = this.getClass().getResource("/").getPath();//获取classP ...