2023-04-02:设计一个仓库管理器,提供如下的方法: 1) void supply(String item, int num, int price) 名字叫item的商品,个数num,价格pri
2023-04-02:设计一个仓库管理器,提供如下的方法:
- void supply(String item, int num, int price)
名字叫item的商品,个数num,价格price。 - int sell(String item, int num)
卖出叫item的商品,个数num个,价格从低到高,返回卖出总价。
如果商品很多,每种商品的数量可能很多,该怎么设计这个结构。
答案2023-04-02:
设计思路
我们需要设计一个仓库管理器,它可以支持以下几种操作:
1.向指定商品中进货一定数量的货物;
2.对指定商品进行售卖,并返回售卖的总价。
为了实现这些功能,我们需要对每种商品维护一个最大堆,堆中存储的是该商品的所有不同价格,按照从低到高的顺序排列。同时,我们还需要一个哈希表,记录每个价格对应的商品数量。
在进货时,我们首先根据传入的商品名称,在哈希表中查找是否已经有该商品信息。如果有,则直接将新货物数量加入相应的价格中;否则,我们就需要创建一个新的最大堆和哈希表项,并将新货物信息添加到其中。
在售卖时,我们需要按照从低到高的价格顺序逐个处理商品。具体来说,我们从最大堆中弹出最低价格的商品,然后查询其数量是否足够售卖。如果数量足够,那么我们将相应的金额累加到总价中,并从哈希表中删除对应的价格项;否则,我们只能将部分商品出售,并将剩余商品放回最大堆中,等待下一次处理。
主要数据结构
为了实现上述功能,我们需要使用以下几种数据结构:
1.哈希表(HashMap):用于记录每个商品的价格和数量信息;
2.最大堆(BinaryHeap):存储每个商品的所有不同价格,并按照从低到高的顺序排列。
具体实现
在 Rust 中,我们可以通过定义一个名为 Store 的结构体来表示每种商品的价格数量信息。该结构体包含两个字段:
1.price_nums:本质上是一个哈希表,记录了每个价格对应的商品数量;
2.heap:是一个最大堆,存储了所有不同价格的商品,便于在售卖时按照价格从低到高进行处理。
struct Store {
price_nums: HashMap<i32, i32>,
heap: BinaryHeap<i32>,
}
impl Store {
fn new() -> Self {
Self {
price_nums: HashMap::new(),
heap: BinaryHeap::new(),
}
}
fn add(&mut self, num: i32, price: i32) {
if let Some(count) = self.price_nums.get_mut(&price) {
*count += num;
} else {
self.price_nums.insert(price, num);
self.heap.push(price);
}
}
fn remove(&mut self, mut num: i32) -> i32 {
let mut money = 0;
while !self.heap.is_empty() && num != 0 {
let price = self.heap.pop().unwrap();
let stores = *self.price_nums.get(&price).unwrap();
if num >= stores {
money += price * stores;
self.price_nums.remove(&price);
num -= stores;
} else {
money += price * num;
self.heap.push(price);
self.price_nums.insert(price, stores - num);
break;
}
}
money
}
}
接下来,我们可以定义一个名为 StoreManager 的结构体,用于管理所有商品的进货和售出操作。该结构体包含一个哈希表 map,键是商品名称,值是对应的 Store 对象。
pub struct StoreManager {
map: HashMap<String, Store>,
}
在 supply 方法中,我们根据传入的商品名称在哈希表中查找是否已经有该商品信息。如果有,则直接将新货物数量加入相应的价格中;否则,我们就需要创建一个新的最大堆和哈希表项,并将新货物信息添加到其中。
在 sell 方法中,我们首先通过商品名称找到对应的 Store 对象,然后调用其 remove 方法进行售卖操作。在这个方法里,我们首先从最大堆中弹出价格最低的商品,然后查看其数量是否足够售卖。如果该商品数量大于等于需要售卖的数量,那么直接将总价增加相应的金额,并删除该商品;否则将总价增加当前售卖所需的金额,并将剩余的商品放回最大堆中。
impl StoreManager {
pub fn supply(&mut self, item: &str, num: i32, price: i32) {
let store = self.map.entry(item.to_string()).or_insert(Store::new());
store.add(num, price);
}
pub fn sell(&mut self, item: &str, num: i32) -> i32 {
self.map.get_mut(item).unwrap().remove(num)
}
}
rust完整代码
use std::collections::{BinaryHeap, HashMap};
struct Store {
price_nums: HashMap<i32, i32>,
heap: BinaryHeap<i32>,
}
impl Store {
fn new() -> Self {
Self {
price_nums: HashMap::new(),
heap: BinaryHeap::new(),
}
}
fn add(&mut self, num: i32, price: i32) {
if let Some(count) = self.price_nums.get_mut(&price) {
*count += num;
} else {
self.price_nums.insert(price, num);
self.heap.push(price);
}
}
fn remove(&mut self, mut num: i32) -> i32 {
let mut money = 0;
while !self.heap.is_empty() && num != 0 {
let price = self.heap.pop().unwrap();
let stores = *self.price_nums.get(&price).unwrap();
if num >= stores {
money += price * stores;
self.price_nums.remove(&price);
num -= stores;
} else {
money += price * num;
self.heap.push(price);
self.price_nums.insert(price, stores - num);
break;
}
}
money
}
}
pub struct StoreManager {
map: HashMap<String, Store>,
}
impl StoreManager {
pub fn new() -> Self {
Self {
map: HashMap::new(),
}
}
pub fn supply(&mut self, item: &str, num: i32, price: i32) {
let store = self.map.entry(item.to_string()).or_insert(Store::new());
store.add(num, price);
}
pub fn sell(&mut self, item: &str, num: i32) -> i32 {
self.map.get_mut(item).unwrap().remove(num)
}
}
fn main() {
let mut manager = StoreManager::new();
manager.supply("apple", 10, 3);
manager.supply("banana", 5, 2);
manager.supply("orange", 8, 4);
let total_price = manager.sell("banana", 3);
println!("Sell 3 bananas: ${}", total_price);
let total_price = manager.sell("banana", 2);
println!("Sell 2 bananas: ${}", total_price);
let total_price = manager.sell("apple", 5);
println!("Sell 5 apples: ${}", total_price);
let total_price = manager.sell("orange", 10);
println!("Sell 10 oranges: ${}", total_price);
}
2023-04-02:设计一个仓库管理器,提供如下的方法: 1) void supply(String item, int num, int price) 名字叫item的商品,个数num,价格pri的更多相关文章
- 设计一个缓存器 ReadLock提高性能
/** * * @描述: 设计一个缓存器 ReadLock提高性能. * @作者: Wnj . * @创建时间: 2017年5月16日 . * @版本: 1.0 . */ public class C ...
- Light Pre-Pass 渲染器----为多光源设计一个渲染器
http://blog.csdn.net/xoyojank/article/details/4460953 作者: Wolfgang Engel, 原文: http://www.wolfgang-en ...
- 2018/04/02 每日一个Linux命令 之 新建/修改/删除群组
-- 新建群组 groupadd [群组名] -- 修改群组名称 groupmod [群组名] [新群组名] -n 修改组名 -g 修改组识别码 -- 删除群组 groupdel [删除的组名] --
- ubuntu12.04打开某一个已安装的软件的方法
1.快捷键win+A,里面显示已安装的软件 2.打开左上角的dash home,即ubuntu标志图,输入想要打开的软件 还有其它方法,探索中... .
- 使用仓库管理器——Sonatype Nexus的九大理由
目前有很多组织使用了一些工具依赖于Maven仓库,但他们并没有采用一个仓库管理器,对于这一点我十分惊讶.可能没人提出来这一点,没人站出来告诉别人使用一个仓库管理器能带来什么好处.我经常能从很多不使用M ...
- java开发中的链式思维 —— 设计一个链式过滤器
概述 最近在弄阿里云的sls日志服务,该服务提供了一个搜索接口,可根据各种运算.逻辑等表达式搜出想要的内容.具体语法可见https://help.aliyun.com/document_detail/ ...
- 「造个轮子」——cicada 设计一个配置模块
前言 在前两次的 cicada 版本中其实还不支持读取配置文件,比如对端口.路由的配置. 因此我按照自己的想法创建了一个 issue ,也收集到了一些很不错的建议. 最终其实还是按照我之前的想法来做了 ...
- 【Android Developers Training】 94. 创建一个空内容提供器(Content Provider)
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 框架源码系列四:手写Spring-配置(为什么要提供配置的方法、选择什么样的配置方式、配置方式的工作过程是怎样的、分步骤一个一个的去分析和设计)
一.为什么要提供配置的方法 经过前面的手写Spring IOC.手写Spring DI.手写Spring AOP,我们知道要创建一个bean对象,需要用户先定义好bean,然后注册到bean工厂才能创 ...
- 设计一个简单的,低耗的能够区分红酒和白酒的感知器(sensor)
学习using weka in your javacode 主要学习两个部分的代码:1.过滤数据集 2 使用J48决策树进行分类.下面的例子没有对数据集进行分割,完全使用训练集作为测试集,所以不符合数 ...
随机推荐
- loadrunner添加/清除 cookies
web_add_cookie("reloadCount=1;domain={Host}"); 清除 cookies web_cleanup_cookies():
- PC端,知乎在不想登录的情况下一打开就弹出登录框的无痛解决办法
基于chrome浏览器 第一步: chrome://settings/content/javascript 第二步:添加禁用项 [*.]zhihu.com
- Python库之os库和logging库的基本使用说明
使用os库操作目录及文件 使用os.sep() 方法获取系统分隔符 print(os.sep) 使用os.name()方法获取操作系统的平台类型 print(os.name) 使用os.getcwd( ...
- Linux shell usage()使用说明
usage()类似于执行文件-help展示的内容,即告诉使用者有哪些参数选项可供使用. usage()格式 点击查看代码 #!/bin/bash usage() { echo "Usage: ...
- ansible用authorized_key模块批量推送密钥到受控主机实现免密登录
一,ansible的authorized_key模块的用途 用来配置密钥实现免密登录: ansible所在的主控机生成密钥后,如何把公钥上传到受控端? 当然可以用ssh-copy-id命令逐台手动处理 ...
- 局部异常因子(Local Outlier Factor, LOF)算法详解及实验
局部异常因子(Local Outlier Factor, LOF)通过计算样本点的局部相对密度来衡量这个样本点的异常情况,可以算是一类无监督学习算法.下面首先对算法的进行介绍,然后进行实验. LOF算 ...
- 在Linux中安装containerd作为kubernetes的容器运行时
概述 从kubernetes1.24开始的版本移除了内置的docker支持,用户可以自行选择需要使用的容器运行时,比如containerd.CRI-O.Docker Engine等等,这里我们采用二进 ...
- php in_array 遍历,in_array大数组查询性能问题
问题最近在实现一个项目接口的时候发现当数组过大的时候,数据返回的速度有点慢.接口数据返回最长反应时间2s,经过反复调试发现代码段耗时最长的部分在in_array()函数.解决过程在stackoverf ...
- 重磅!AWS升级对Apache Hudi的集成
全球最大云厂商AWS的 Athena 团队又更新了 Athena 与 Apache Hudi 的集成,以支持新功能及最新的 0.8.0 社区版本.早在Apache Hudi还处于孵化阶段时,AWS A ...
- 【过滤器设计模式详解】C/Java/JS/Go/Python/TS不同语言实现
简介 过滤器模式(Filter Pattern)或标准模式(Criteria Pattern),是一种结构型模式.这种模式允许使用不同的标准条件来过滤一组对象,并通过逻辑运算的方式把各条件连接起来,它 ...