轮渡模拟
一、简单介绍
这是在博客园潜水几个月第一次开始想要写点东西,一是记录自己的学习过程,二是和大家分享同时接受大家的指正,再者可以多交一些朋友,我微博地址在公告栏里,互粉哦。。。。这是最近上数据结构时的练习题,首先是队列的实现,再用队列去模拟解决一个实际问题——轮渡模拟。
二、问题分析
2.1 问题描述:
轮渡模拟:有一个渡口,每条渡船能一次性装载10辆汽车过河,车辆分为客车和货车两类。 上渡轮有如下规定:同类汽车先到先上船,客车先于货车上船,轮渡每10分钟一班。 模拟一小时内汽车上渡轮的过程。 汽车:包含一个汽车类型属性,一个到达时间属性,到达时间随机产生。 轮渡:包含一个装车情况的属性,一个出发时间的属性。 输出:1小时内六班轮渡的装车情况。 2.2 实现说明:
当拿到这个问题时,分析问题后觉得要比较好的使各个事件不相互影响地模拟轮渡情况,需要用到多线程,但因为以前都是在Linux环境下编程,没有在Windows上实现过多线程编程,所以也不知道在具体实现中是否会存在什么问题。实现时在主函数中创建了三个线程:其中两个 线程 分别是客车和货车随机产生(到达),并携带时间信息进入到相应的队列;还有一个是用于做计数器用。
三、实现代码
3.1测试
#include <iostream> #include <ctime> #include <cstdlib> #include <windows.h> #include <process.h> #include " sqQueue.h " // 包含自定义队列类 using namespace std; #define MAX_NUM 10 // 渡轮最大装载数量 typedef enum {PassengerCar, FreightCar}CarType; // 汽车类型 typedef struct { CarType type; // 汽车类型 time_t arriveTime; // 汽车到达时间 }Car; typedef struct { int size; // 渡轮当前装载汽车数量 time_t startTime; // 渡轮出发时间 }Ferry; SqQueue <Car> pCarQueue( 61 ); // 定义队列,用于存放客车的队列,模拟一分钟最多60辆汽车 SqQueue<Car> fCarQueue( 61 ); // 定义队列,用于存放货车的队列 int startTimeFlag = 0 ; // 定义渡轮出发标志 int countLength = 6 ; // 计数长度 unsigned _stdcall threadCountFun( void * pArguments) { while (countLength > 0 ) { Sleep( 10000 ); // 计数10秒 startTimeFlag = 1 ; countLength -- ; } return 0 ; }
bool ferryFun() // 函数:处理渡轮到达,装载,出发等 { int count = 1 ; // 渡轮计数 while (count< 7 ) { Ferry ferry; ferry.size = 0 ; // 初始轮渡装载汽车数量 while ( 1 ) { if (ferry.size < 10 ) // 轮渡未满 { if (!pCarQueue.isEmpty_SqQueue() && ! fCarQueue.isEmpty_SqQueue() && pCarQueue.top_SqQueue().arriveTime == fCarQueue.top_SqQueue().arriveTime) { // 当两队列对头汽车到达时间相同时,客车先上船 cout<< " 一辆客车上船...其到达渡口时间: " ; cout <<ctime(& pCarQueue.top_SqQueue().arriveTime); pCarQueue.pop_SqQueue(); ferry.size ++ ; }
else if (!pCarQueue.isEmpty_SqQueue() && ! fCarQueue.isEmpty_SqQueue() && pCarQueue.top_SqQueue().arriveTime < fCarQueue.top_SqQueue().arriveTime) { // 客车先到 cout<< " 一辆客车上船...其到达渡口时间: " ; cout <<ctime(& pCarQueue.top_SqQueue().arriveTime); pCarQueue.pop_SqQueue(); ferry.size ++ ; }
else if (!fCarQueue.isEmpty_SqQueue()) // 货车先到 { cout << " 一辆货车上船...其到达渡口时间: " ; cout <<ctime(& fCarQueue.top_SqQueue().arriveTime); fCarQueue.pop_SqQueue(); ferry.size ++ ; } }
if ( 1 == startTimeFlag) { time( & ferry.startTime); cout << " 时间过去 " << 10 *count<< " 分钟 " ; cout << " 第 " <<count<< " 条渡轮开走, " << " 装有汽车 " ; cout <<ferry.size<< " 辆 " << " ,出发时间: " <<ctime(& ferry.startTime); count ++ ; startTimeFlag = 0 ; break ; }
} }
return true ; } unsigned _stdcall threadPCarFun( void * pArguments) // 客车处理函数 { srand(time( 0 )); while (! pCarQueue.isFull_SqQueue()) { Car car; if ( 1 == rand()% 14 ) // 1(客车) { car.type = PassengerCar; time( &car.arriveTime); // 记录到达时间 pCarQueue.push_SqQueue(car); // cout<<"P: "<<car.arriveTime<<endl; } Sleep( 200 ); // 200和10意义:每2毫秒中有十分之一概率产生(到达)一辆汽车(客车和货车) } return 0 ; } unsigned _stdcall threadFCarFun( void * pArguments) // 货车处理函数 { srand(time( 0 )); while (! fCarQueue.isFull_SqQueue()) { Car car; if ( 2 == rand()% 14 ) // 2(货车) { car.type = FreightCar; time( &car.arriveTime); // 记录到达时间 fCarQueue.push_SqQueue(car); // cout<<"H: "<<car.arriveTime<<endl; } Sleep( 200 ); // 200和14意义:每1毫秒中有十分之一概率产生(到达)一辆汽车 } // 测试这个频率能看到装满和没装满的情况 return 0 ; } int main( int argc, char ** argv) { HANDLE hThread_P, hThread_F, hThread_Count; unsigned int threadID_P, threadID_F, threadID_Count; hThread_P = (HANDLE) _beginthreadex(NULL, 0 , &threadPCarFun, NULL, 0 , & threadID_P); hThread_F = (HANDLE) _beginthreadex(NULL, 0 , &threadFCarFun, NULL, 0 , & threadID_F); hThread_Count = (HANDLE) _beginthreadex(NULL, 0 , &threadCountFun, NULL, 0 , & threadID_Count); ferryFun(); cout << " \n汽车排队中....直至队满... " << endl; WaitForSingleObject(hThread_P, INFINITE ); WaitForSingleObject(hThread_F, INFINITE ); WaitForSingleObject(hThread_Count, INFINITE );
CloseHandle(hThread_P); CloseHandle(hThread_F); CloseHandle(hThread_Count); return 0 ; }
运行结果:
3.2以下是自己用模板类实现的循环队列:
自定义队列类(sqQueue.h)
#ifndef SQQUEUE_H #define SQQUEUE_H #define Q_MAX_LENGTH 100 template <typename T> class SqQueue { public : SqQueue( int length_SqQueue = Q_MAX_LENGTH); virtual ~ SqQueue(); bool push_SqQueue( const T& e); bool pop_SqQueue(); bool isEmpty_SqQueue(); bool isFull_SqQueue(); T & top_SqQueue(); const T& top_SqQueue() const ; int size_SqQueue(); void display_SqQueue(); private : T * data; int front; int rear; int length; }; /* 构造函数,初始化队列 */ template <typename T> SqQueue <T>::SqQueue( int length_SqQueue) { data = new T[length_SqQueue]; front = rear = 0 ; length = length_SqQueue; } /* 析构函数 */ template <typename T> SqQueue <T>::~ SqQueue() { delete []data; } /* 判空操作 */ template <typename T> bool SqQueue<T> ::isEmpty_SqQueue() { if (front == rear) return true ; else return false ; } /* 判满操作 */ template <typename T> bool SqQueue<T> ::isFull_SqQueue() { if ((rear+ 1 )%length == front) return true ; else return false ; } /* 入队操作 */ template <typename T> bool SqQueue<T>::push_SqQueue( const T& e) { if (! isFull_SqQueue()) { data[rear] = e; rear = (rear+ 1 )% length; return true ; } return false ; } /* 出队操作 */ template <typename T> bool SqQueue<T> ::pop_SqQueue() { if (! isEmpty_SqQueue()) { front = (front+ 1 )% length; } return false ; } /* 得到对头元素 */ template <typename T> T & SqQueue<T> ::top_SqQueue() { if (! isEmpty_SqQueue()) { return data[front]; } // cout<<"队列空"<<endl; } /* 得到对头元素, const版本 */ template <typename T> const T& SqQueue<T>::top_SqQueue() const { if (! isEmpty_SqQueue()) { return data[front]; } // cout<<"队列空"<<endl; } /* 测队长 */ template <typename T> int SqQueue<T> ::size_SqQueue() { return (rear-front+length)% length; } /* 遍历打印操作 */ template <typename T> void SqQueue<T> ::display_SqQueue() { int i = front; while (i != rear) { std::cout <<data[i]<< " " ; i = (i+ 1 )% length; } std::cout << endl; } #endif
分类: 数据结构
标签: 数据结构
作者: Leo_wl
出处: http://www.cnblogs.com/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did47912