模拟自动售货机的找零程序。需求描述如下:
1、程序根据用户投入货币的面额及其数量,在扣除购买的商品价额后,进行找零。
2、程序需要根据售货机内现存的各种货币面额和数量,在优先分配大面额货币的条件下,进行找零。
3、暂时仅支持整数找零。
4、实际的自动售货机找零是串行化操作,因此不考虑多线程同步问题。
package org.tang.change;
/**
* 货币枚举类
* @author Tang
*
*/
public enum Currency {
/**
* 货币面额
*/
HUNDRED_YUAN(100),
FIFTY_YUAN(50),
TWENTY_YUAN(20),
TEN_YUAN(10),
FIVE_YUAN(5),
ONE_YUAN(1);
/**
* 货币面额值
*/
private int value;
public int getValue() {
return value;
}
private Currency(int value){
this.value = value;
}
}
定义货币面额的枚举类。在需要增加面额情况下,可以扩展词枚举类。但是需要保证按照面额降序排列,这是为了实现较大面额货币将被优先分配找零的目的。
package org.tang.change;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* 自动售货机类
* @author Tang
*
*/
public class VendingMachine {
private static final VendingMachine MACHINE = new VendingMachine();
/**
* key表示货币面额
* value表示该面额货币在此售货机当中的存量
*/
private static Map<Currency, Integer> moneyPool = new HashMap<Currency, Integer>();
private static Log logger = LogFactory.getLog(VendingMachine.class);
static {
initMoneyPool();
}
private VendingMachine(){}
/**
* 返回自动售货机实例
* @return
*/
public static VendingMachine getInstance(){
return MACHINE;
}
/**
* 初始化零钱库存
*/
private static void initMoneyPool(){
moneyPool.put(Currency.ONE_YUAN, 4);
moneyPool.put(Currency.FIVE_YUAN, 8);
moneyPool.put(Currency.TEN_YUAN, 5);
moneyPool.put(Currency.TEN_YUAN, 5);
moneyPool.put(Currency.TWENTY_YUAN, 3);
moneyPool.put(Currency.FIFTY_YUAN, 2);
moneyPool.put(Currency.HUNDRED_YUAN, 0);
if(logger.isInfoEnabled()){
logger.info("初始化售货机零钱库量:"+getStockBalance());
}
}
/**
* 将收到的钱放入零钱库
*/
private void put(Map<Currency,Integer> putMap){
if(logger.isInfoEnabled()){
logger.info("put操作前零钱库存量:"+getStockBalance());
}
for(Map.Entry<Currency, Integer> entry : putMap.entrySet()){
Integer count = moneyPool.get(entry.getKey());
moneyPool.put(entry.getKey(),(count == null ? 0:count) + entry.getValue());
}
if(logger.isInfoEnabled()){
logger.info("put操作后零钱库存量:"+getStockBalance());
}
}
/**
* 从零钱库中取出若干零钱
* @param takeMap
*/
private void take(Map<Currency,Integer> takeMap){
if(logger.isInfoEnabled()){
logger.info("take操作前零钱库存量:"+getStockBalance());
}
for(Map.Entry<Currency, Integer> entry : takeMap.entrySet()){
Integer count = moneyPool.get(entry.getKey());
moneyPool.put(entry.getKey(),(count == null ? 0:count) - entry.getValue());
}
if(logger.isInfoEnabled()){
logger.info("take操作后零钱库存量:"+getStockBalance());
}
}
/**
* 返回当前库中零钱总额
* @return
*/
public static int getStockBalance() {
return Currency.ONE_YUAN.getValue() * moneyPool.get(Currency.ONE_YUAN)
+ Currency.FIVE_YUAN.getValue()
* moneyPool.get(Currency.FIVE_YUAN)
+ Currency.TEN_YUAN.getValue()
* moneyPool.get(Currency.TEN_YUAN)
+ Currency.TWENTY_YUAN.getValue()
* moneyPool.get(Currency.TWENTY_YUAN)
+ Currency.FIFTY_YUAN.getValue()
* moneyPool.get(Currency.FIFTY_YUAN)
+ Currency.HUNDRED_YUAN.getValue()
* moneyPool.get(Currency.HUNDRED_YUAN);
}
/**
* 找零钱
* @return
*/
public Map<Currency,Integer> giveChange(int cost, Map<Currency,Integer> putMap) {
if(putMap == null){
throw new NullPointerException();
}
int putAmount = getPutAmount(putMap);
int payAmount = putAmount - cost;
if(logger.isInfoEnabled()){
logger.info("您需要为商品支付"+cost+"元,现收您"+putAmount+"元,还需找您"+payAmount+"元。");
}
if(cost <= 0 || putAmount == 0 || payAmount < 0){
throw new IllegalArgumentException("您的入参错误");
}
put(putMap);
Map<Currency,Integer> rtMap = new HashMap<Currency,Integer>(2);
for(Currency cur : Currency.values()){
if(payAmount == 0){
break;
}
Integer count = moneyPool.get(cur);
if(count == null){
continue;
}
if(payAmount - cur.getValue() == 0){
rtMap.put(cur, 1);
payAmount = 0;
break;
}
if(payAmount - cur.getValue() > 0 && payAmount / cur.getValue() > 0 && count >= (payAmount / cur.getValue())){
rtMap.put(cur, payAmount / cur.getValue());
payAmount = payAmount % cur.getValue();
}
}
if(payAmount != 0){
take(putMap);
throw new IllegalStateException("自动售货机零钱不够了。。。您的钱将自动退还");
}
take(rtMap);
return rtMap;
}
/**
* 返回收到的总金额
* @return
*/
private int getPutAmount(Map<Currency,Integer> putMap){
if(putMap == null || putMap.isEmpty()){
return 0;
}
int val = 0;
for(Map.Entry<Currency,Integer> entry : putMap.entrySet()){
val += entry.getKey().getValue()*entry.getValue();
}
return val;
}
}
package org.tang.change;
import java.util.HashMap;
import java.util.Map;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
Map<Currency,Integer> map = new HashMap<Currency,Integer>();
//投入售货机1张50元钞
map.put(Currency.FIFTY_YUAN, 1);
//需要为商品支付金额
int cost = 31;
VendingMachine machine = VendingMachine.getInstance();
Map<Currency,Integer> rtMap = machine.giveChange(cost,map);
System.out.println("\r自动售货机找零情况如下:");
for(Map.Entry<Currency, Integer> entry : rtMap.entrySet()){
System.out.println(entry.getValue()+"张"+entry.getKey().getValue()+"元");
}
}
}
INFO 2012-10-23 20:10:35,718 org.tang.change.VendingMachine: 初始化售货机零钱库量:254
INFO 2012-10-23 20:10:35,720 org.tang.change.VendingMachine: 您需要为商品支付30元,现收您50元,还需找您20元。
INFO 2012-10-23 20:10:35,721 org.tang.change.VendingMachine: put操作前零钱库存量:254
INFO 2012-10-23 20:10:35,721 org.tang.change.VendingMachine: put操作后零钱库存量:304
INFO 2012-10-23 20:10:35,722 org.tang.change.VendingMachine: take操作前零钱库存量:304
INFO 2012-10-23 20:10:35,722 org.tang.change.VendingMachine: take操作后零钱库存量:284
自动售货机找零情况如下:
1张20元
分享到:
相关推荐
自动售货机程序通常涉及货币识别、商品选择、交易处理和找零计算等基本功能。在Quartus II中,我们可以利用Verilog模块化的设计思想,将这些功能分解为多个子模块,如货币检测模块、商品选择模块、计数器模块和控制...
总结来说,这个“自动售货机的模拟控制PLC程序”涵盖了PLC编程、自动售货机工作原理、I/O控制、模拟测试等多个知识点。通过深入理解并应用这些知识,我们可以设计和优化自动售货机的控制逻辑,提升其运行效率和用户...
在本项目"自动售货机程序项目.zip"中,我们主要探讨的是如何使用S7-1200 PLC来控制自动售货机的运作。 一、PLC1200概述 S7-1200系列PLC是西门子SIMATIC家族的一员,设计紧凑,功能强大且易于集成到自动化系统中。它...
在自动售货机MFC项目中,我们主要探讨的是如何利用计算机编程技术模拟现实生活中自动售货机的工作流程。这个项目的核心是实现一个用户友好、功能完善的自动化交易系统,能够处理货币输入、商品选择、找零计算以及...
本资料主要围绕三菱PLC在自动售货机中的应用,提供了一段梯形图程序,对初学者来说是一份很好的学习资源。 首先,我们要理解PLC的基本工作原理。PLC通过接收来自传感器的输入信号,然后按照预设的梯形图程序逻辑...
《S7-1200自动售货机程序项目》是一个基于西门子S7-1200 PLC(可编程逻辑控制器)的自动化工程案例,它涵盖了工业自动化中的多个重要知识点,对于学习和理解PLC编程、自动售货机控制逻辑以及工业4.0的应用具有极大的...
自动售货机VHDL程序与仿真是数字逻辑设计领域中的一个重要实例,它结合了硬件描述语言VHDL(Very High Speed Integrated Circuit Hardware Description Language)和电路仿真技术,用于实现电子设备,特别是可编程...
在给定的“自动售货机C++程序设计”文档中,主要展示了如何使用C++编程语言实现一个简单的自动售货机模拟系统。这个系统包括了用户与售货机交互的多个关键功能,如查看商品列表、投币、选择商品、找零等。下面将详细...
自动售货机程序的核心在于其逻辑控制,包括接收用户输入(硬币或纸币识别)、商品选择、找零计算、货物释放等步骤。在Verilog中,这些功能可以被抽象为多个子模块,每个子模块负责特定的任务,如货币识别模块可能...
【自动售货机模拟】项目基于Visual Basic(VB)编程语言,旨在构建一个虚拟的自动售货机系统,提供用户友好的界面和真实的购物体验。在这个项目中,我们将探讨VB的基础知识,事件驱动编程,控件使用,以及如何实现...
在本项目中,"C++超市自动售货机模拟版"是一个使用C++语言编写的程序,用于模拟现实生活中超市的自动售货机操作。这个程序可能会包含一系列类和函数,用于实现货币识别、商品选择、交易处理等功能,旨在帮助初学者...
本项目“基于VHDL的自动售货机程序”正是利用VHDL来实现一个模拟自动售货机的功能,允许用户进行商品选择、投币和找零操作。 在Quartus环境中,VHDL代码可以被编译、仿真和综合,最终在FPGA上实现硬件功能。Quartus...
通过创建一个模拟自动售货机的程序,学生可以深入理解实际问题的计算机解决方案。 首先,我们需要理解自动售货机的基本工作流程。它通常涉及用户输入(如选择商品、投入硬币)、计算、交易处理(如找零、确认购买)...
自动售货机模拟程序是计算机科学中常见的课程设计项目,它可以帮助学生理解基本的编程概念,如结构化数据处理、用户交互以及简单的图形界面设计。在这个C语言实现的项目中,我们关注的重点在于如何构建一个功能完备...
《自动售货机C++模拟系统详解》 自动售货机是现代生活中常见的便利设施,其内部复杂的逻辑处理和交互设计往往蕴含着丰富的计算机编程知识。在这个C++模拟项目中,我们将深入探讨如何构建一个自动售货机系统,实现...
这个系统的目标是模拟真实的自动售货机功能,包括接受硬币、识别硬币面额、存储硬币、提供商品以及找零。 【Quartus II工具介绍】 Quartus II是Altera公司(现为Intel公司)开发的一款综合、仿真、适配、编程和...
【饮料自动售货机源程序】是一个C++编程示例,由孔令德和叶瑶设计,用于模拟实际生活中饮料自动售货机的工作流程。该程序包含三个主要类:`moneycounter`、`goodsinfo` 和 `drinkmachine`。 1. `moneycounter` 类:...
### 自动售货机的程序相关知识点 #### 一、自动售货机程序设计概述 自动售货机是一种能够自动售卖商品的机器,通常通过投币或者电子支付的方式完成交易。在现代技术的支持下,自动售货机不仅能够提供简单的饮料、...
该自动售货机的设计是基于VHDL编程语言,用于在FPGA(Field-Programmable Gate Array)上实现。这个项目旨在通过实践巩固和应用数字电路系统设计的知识,加深对FPGA和数字电路应用技术的理解,以及熟悉EDA(电子设计...