zoukankan      html  css  js  c++  java
  • 轮渡模拟

    一、简单介绍

        这是在博客园潜水几个月第一次开始想要写点东西,一是记录自己的学习过程,二是和大家分享同时接受大家的指正,再者可以多交一些朋友,我微博地址在公告栏里,互粉哦。。。。这是最近上数据结构时的练习题,首先是队列的实现,再用队列去模拟解决一个实际问题——轮渡模拟。

    二、问题分析   

    2.1 问题描述:

    • 轮渡模拟:有一个渡口,每条渡船能一次性装载10辆汽车过河,车辆分为客车和货车两类。
    • 上渡轮有如下规定:同类汽车先到先上船,客车先于货车上船,轮渡每10分钟一班。
    • 模拟一小时内汽车上渡轮的过程。
    • 汽车:包含一个汽车类型属性,一个到达时间属性,到达时间随机产生。
    • 轮渡:包含一个装车情况的属性,一个出发时间的属性。
    • 输出:1小时内六班轮渡的装车情况。

    2.2 实现说明:

    • 轮渡不管是否装满10秒钟一班,一共进行6班共一分钟;
    • 期间的汽车到来时间及类型是随机的;
    • 初始当前已有一班渡轮停靠在渡口;

        当拿到这个问题时,分析问题后觉得要比较好的使各个事件不相互影响地模拟轮渡情况,需要用到多线程,但因为以前都是在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
    复制代码
     
    分类: 数据结构
    标签: 数据结构
  • 相关阅读:
    smtplib文字邮件的发送
    接口测试框架分析
    UnitTest框架的快速构建与运行
    Appium + Python App自动化第一个脚本
    3个必备cookie实用方法
    单元测试框架的选择
    快速构建一个完整的Selenium框架
    SSH原理与运用
    springboot 集成 spring-data-elasticsearch
    Java 集合排序
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2714805.html
Copyright © 2011-2022 走看看