最近在B站学习了北京大学的北京大学-数据结构与算法Python版 https://www.bilibili.com/video/BV1TJ411Q7zL
由于同时还在学习rust,所以突然想将其里面的数据结构和算法用rust实现一遍
准备一步步来,这次先实现一个教案中的打印机任务模拟,仿照原版的python代码先依样画葫芦
//一步步来先用最简单的vec包装一个Queue
pub struct Queue<T>{
data : Vec<T>,
}
impl<T> Queue<T>{
pub fn new() -> Queue<T>{
let mut data : Vec<T> = Vec::new();
let queue = Queue
{
data : data,
};
queue
}
pub fn isEmpty(&self) -> bool{
self.data.is_empty()
}
pub fn enqueue(&mut self,item:T){ //入队列
self.data.insert(0, item);
}
pub fn dequeue(&mut self) -> T{ //出队列
self.data.pop().unwrap()
}
pub fn size_of(&self) -> usize{
self.data.len()
}
}
//然后是打印机队列的模拟程序
use crate::queue::Queue;
use rand::Rng; //这里需要在Cargo.toml的[dependencies]引入rand = "0.3.17"
struct Printer{
pagerate : i32, //打印速率,每分钟能打多少页
currentTask : Option<Task>, //当前任务,这里用Option包装一下
timeRemaining : i64, //剩余时间(s)
}
impl Printer{
fn new(pp:i32)->Self{ //初始化
Printer{
pagerate:pp,
currentTask : None,
timeRemaining :0,
}
}
fn tick(&mut self){ //任务执行期间,对已经计算好的执行任务所需时间-1
if let Some(_) = &self.currentTask{
self.timeRemaining -=1;
if self.timeRemaining <= 0{
self.currentTask = None;
}
}
}
fn busy(&self) -> bool{ //当前任务不为None,既为繁忙状态
if let Some(_) = &self.currentTask{
return true;
}else{
return false;
}
}
fn startNext(&mut self,newTask:Task){
//打印新作业,这里剩余时间的计算方式 = 下一个任务需要打印的页数 * 60 / 打印速率
//假设打印20页,每分钟只能打印5页,也就是说每12秒打印一页,总共需要20*12=240秒
self.timeRemaining = (newTask.getPages() * 60 / self.pagerate) as i64;
self.currentTask = Some(newTask);
}
}
struct Task{
timestamp : i64,
pages : i32,
}
impl Task{
fn new(time:i64)->Self{
Task{
timestamp:time, //任务发起的时间
//随机生成打印页数,范围1张到20张
pages : rand::thread_rng().gen_range(1, 21),
}
}
fn getStamp(&self) -> i64{
self.timestamp
}
fn getPages(&self) -> i32{
self.pages
}
fn waitTime(&self,currenttime : i64) -> i64{
currenttime - self.timestamp //任务等待时间=任务执行的时间-任务发起的时间
}
}
fn newPrintTask() -> bool{ //新建任务,有1/180的概率发起打印任务
let mut rng =rand::thread_rng();
let num : i32 = rng.gen_range(1,181);
if num == 180{
return true;
}else{
return false;
}
}
fn simulation(numSeconds:i64,pagersPerminute:i32){
let mut labprinter = Printer::new(pagersPerminute); //建立一个打印机类实例
let mut printQueue : Queue<Task> = Queue::new(); //建立一个打印任务队列
let mut waitingtimes : Vec<i64> = Vec::new(); //建立一个打印任务的等待时间vec
for currentSecond in 0..numSeconds{ //开始打印计时
if newPrintTask(){ //新建任务,有1/180的概率发起打印任务
let task = Task::new(currentSecond); //发起成功,建立一个任务类
printQueue.enqueue(task); //将任务先放入队列
}
if !labprinter.busy() && !printQueue.isEmpty(){ //只有打印机不繁忙和任务队列不为空的情况下
let nextTask : Task = printQueue.dequeue(); //从队列中获取一个新任务
waitingtimes.push(nextTask.waitTime(currentSecond)); //计算等待时间,并将其push到任务等待vec中
labprinter.startNext(nextTask); //执行新任务的打印
}
labprinter.tick();//时间-1s
}
let eee : i64 = waitingtimes.iter().sum(); //合集等待vec中的等待时间
let averageWait :f64 = (eee / waitingtimes.len() as i64) as f64; //计算平均等待时间
println!("Average Wait {} secs {} tasks remaining",averageWait,printQueue.size_of());
}
pub fn run(){
for _ in 0..10{ //运行10次模拟
simulation(3600, 5); //打印1小时,每分钟能打5页
}
}
版权声明:本文为zzcwing原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。