轮渡模拟
一、简单介绍
这是在博客园潜水几个月第一次开始想要写点东西,一是记录自己的学习过程,二是和大家分享同时接受大家的指正,再者可以多交一些朋友,我微博地址在公告栏里,互粉哦。。。。这是最近上数据结构时的练习题,首先是队列的实现,再用队列去模拟解决一个实际问题——轮渡模拟。
二、问题分析
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://HdhCmsTestcnblogs测试数据/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did47912