第3章-队列(2020.03.19)

第3章-队列

(开始勇敢地和C++作斗争)

1. 环形队列【中等】

(环形队列)请用顺序存储实现环形的数据结构CirQueue。你所实现的环形队列应包括:出队、入队、访问队首、判断队列是否已满,判断队列是否为空等功能。利用你实现的CirQueue实现输入整数序列的顺序输出。
【输入】整数序列以-1结束,序列长度小于100
【输出】输入整数序列的顺序序列
例如:
【输入】3 9 8 2 5 -1
【输出】3 9 8 2 5

#include <iostream>
#define max 150
using namespace std;

class CirQueue
{
public:
    CirQueue();
    bool Empty()const;
    bool Full()const;
    void serve();
    void append(int &item);
    void retrive(int &item)const;
private:
    int cnt;//cnt元素个数
    int Front,rear;
    int entry[max];
};

int main()
{
    int a;
    cin >> a;
    CirQueue A;

    while(a!=-1){
        int &temp = a;
        A.append(temp);
        cin >> a;
    }
    while(!A.Empty()){
        int &temp = a;
        A.retrive(temp);
        cout <<a <<' ';
        A.serve();
    }
    return 0;
}

CirQueue::CirQueue()
{
    cnt = 0;
    rear = max-1;
    Front = 0;
}

bool CirQueue::Empty()const
{
    bool outcome = false;
    if(cnt == 0) outcome = true;
    return outcome;
}

bool CirQueue::Full()const
{
    bool outcome = true;
    if(cnt < max ) outcome = false;
    return outcome;
}

void CirQueue::append(int &item)
{
    if(!Full()){
        cnt++;
        rear = ((rear+1) == max)? 0: (rear+1);
        entry[rear] = item;
    }
}

void CirQueue::serve()
{
    if(!Empty()){
        cnt--;
        Front = (Front+1) == max? 0: (Front+1);
    }
}

void CirQueue::retrive(int &item)const
{
    if(!Empty()) item = entry[Front];
}
2. 双端队列【中等】

(双端队列)The word deque (pronounced either “deck” or “DQ”) is a shortened form of double-ended queue and denotes a list in which entries can be added or removed from either the first or the last position of the list, but no changes can be made elsewhere in the list. Thus a deque is a generalization of both a stack and a queue. The fundamental operations on a deque are append_front, append_rear, serve_front, serve_rear, retrieve_front, and retrieve_rear.
参考:https://en.wikipedia.org/wiki/Double-ended_queue
请实现deque,并解决如下问题:
在许多应用类软件的开发中都需要有保存用户历史操作的功能,例如word需要存储用户的编辑操作历史,浏览器需要存储用户浏览网页的历史,搜索栏需要保存最近的搜索记录等。请编写程序存储用户最近的n条操作记录,并将其按照时间顺序(由近到远)输出。
【输入】
设置软件需要最大保留的历史操作条数n(1<=n<=50)
用户的历史操作序列(数值可能大于n)且操作序列用大写字母来表示。
【输出】最近的n条操作序列(若操作序列长度小于n,则全部输出)
例如:
【输入】
5
A B C D
【输出】
D C B A
【输入】
5
A B C D E F G
【输出】
G F E D C

#include <iostream>
#include <stdio.h>
#define max 150
using namespace std;

class DeQueue
{
public:
    DeQueue();
    bool Empty()const;
    bool Full()const;
    void front_serve();//从队首弹出
    void rear_serve();//从队尾弹出
    //void front_append(char &item);
    void rear_append(char &item);//从队尾进入
    //void front_retrive(char &item)const;
    void rear_retrive(char &item)const;//取队尾元素
    int Size();
private:
    int cnt;//cnt元素个数
    int Front,Rear;
    int entry[max];
};

int main()
{
    int n;
    cin >> n;
    getchar();
    DeQueue A;
    char ch;
    char &temp = ch;
    while(scanf("%c",&ch) != EOF)
    {
        if(A.Size() > n){
            A.front_serve();
        }
        A.rear_append(temp);
        getchar();
    }
    int CNT = A.Size();
    if(CNT > n){
        for(int i=0; i<n; i++){
            A.rear_retrive(temp);
            A.rear_serve();
            cout <<ch <<' ';
        }
    }
    else{
         for(int i=0; i<CNT; i++){
            A.rear_retrive(temp);
            A.rear_serve();
            cout <<ch <<' ';
        }
    }
    return 0;
}

DeQueue::DeQueue()
{
    cnt = 0;
    Rear = max-1;
    Front = 0;
}

int DeQueue::Size()
{
    return cnt;
}

bool DeQueue::Empty()const
{
    bool outcome = false;
    if(cnt == 0) outcome = true;
    return outcome;
}

bool DeQueue::Full()const
{
    bool outcome = true;
    if(cnt < max ) outcome = false;
    return outcome;
}

/*void DeQueue::front_append(char &item)
{
    if(!Full()){
        cnt++;
        Front = ((Front-1) == -1)? max-1: (Front-1);
        entry[Front] = item;
    }
}*/

void DeQueue::rear_append(char &item)
{
    if(!Full()){
        cnt++;
        Rear = ((Rear+1) == max)? 0: (Rear+1);
        entry[Rear] = item;
    }
}

void DeQueue::front_serve()
{
    if(!Empty()){
        cnt--;
        Front = (Front+1) == max? 0: (Front+1);
    }
}

void DeQueue::rear_serve()
{
    if(!Empty()){
        cnt--;
        Rear = ((Rear-1) == -1)? max-1: (Rear-1);
    }
}

/*void DeQueue::front_retrive(char &item)const
{
    if(!Empty()) item = entry[Front];
}*/

void DeQueue::rear_retrive(char &item)const
{
    if(!Empty()) item = entry[Rear];
}
3. 字符串的平衡性分析【中等】

(字符串的平衡性分析)P92 Programming Project 3.3
Write a program that will read one line of input from the terminal. The input is supposed to consist of two parts separated by a colon :. As its result, your program should produce a single character as follows:
N No colon on the line.
L The left part (before the colon) is longer than the right.
R The right part (after the colon) is longer than the left.
D The left and right parts have the same length but are different.
S The left and right parts are exactly the same.
Examples:
Input Output
Sample Sample N
Left:Right R
Sample:Sample S
Dog:Cat D
Rabbit:Dog L
【输入】
字符串的数量n
第2到n+1行分别输入需要分析的字符串
【输出】
N条字符串的判断结果
例如:
【输入】
3
Sample Sample
Dog:Cat
Rabbit:Dog
【输出】
N
D
L

#include <iostream>
#include <bits/stdc++.h>
#define max 150
using namespace std;

class CirQueue
{
public:
    CirQueue();
    bool Empty()const;
    bool Full()const;
    void serve();
    void append(char &item);
    void retrive(char &item)const;
private:
    int cnt;//cnt元素个数
    int Front,rear;
    int entry[max];
};

int main()
{
    int n,i;
    cin >> n;
    getchar();
    char ch;
    char &temp = ch;
    while(n--)
    {
        CirQueue A;//注意!!!要复位
        ch = getchar();
        int flag = 0;
        char str[max] = {'\0'};
        i=0;
        while(ch != '\n'){
            if(ch == ':')
                flag = 1;
            str[i++] = ch;
            ch = getchar();
        }
        if(flag == 0){
            cout <<"N" <<endl;
            continue;
        }

        i=0;
        while(str[i] != ':'){
            temp = str[i];
            A.append(temp);
            i++;
        }

        //判断长度
        int len1 = i;
        int len2 = strlen(str)-1-i;
        if(len1 > len2){
            cout <<"L" <<endl;
            continue;
        }
        if(len1 < len2){
            cout <<"R" <<endl;
            continue;
        }

        temp = ch;
        flag = 1;
        for(i=i+1; i<strlen(str); i++){
            A.retrive(temp);
            if(ch != str[i]){
                flag = 0;
            }
            A.serve();
        }
        if(flag == 0) cout <<"D" <<endl;
        else cout <<"S" <<endl;
    }
    return 0;
}

CirQueue::CirQueue()
{
    cnt = 0;
    rear = max-1;
    Front = 0;
}

bool CirQueue::Empty()const
{
    bool outcome = false;
    if(cnt == 0) outcome = true;
    return outcome;
}

bool CirQueue::Full()const
{
    bool outcome = true;
    if(cnt < max ) outcome = false;
    return outcome;
}

void CirQueue::append(char &item)
{
    if(!Full()){
        cnt++;
        rear = ((rear+1) == max)? 0: (rear+1);
        entry[rear] = item;
    }
}

void CirQueue::serve()
{
    if(!Empty()){
        cnt--;
        Front = (Front+1) == max? 0: (Front+1);
    }
}

void CirQueue::retrive(char &item)const
{
    if(!Empty()) item = entry[Front];
}
4. 车厢调度【中等】

(车厢调度)某城市有一个火车站,铁轨铺设如下图所示。有n节车厢从主轨道左边驶入车站,按进站顺序编号为1-n。你的任务是判断是否能让它们按照某种特定的顺序进入主轨道右边并驶出车站。为了重组车厢,你可以借助辅轨道停放车厢(驶入辅轨道的车厢必须按照相同的顺序驶出)。也就是说,对于每个车厢,可以从主轨道开到右边,也可以沿辅轨道开到右边,但一旦车厢停放进辅轨道,便只能沿辅轨道进入主轨道右边。例如,有5节车厢以1、2、3、4、5的顺序依次进入,要求以3、4、1、5、2的顺序驶出,则可以先将1、2车厢停放入辅轨道,将3、4沿主轨道开向右边,接着,使停放在辅轨道的1车厢驶出,将5沿主轨道开向右边,最后将停放在辅轨道的2车厢驶出,完成调度。

【输入】第一行是一个正整数n,表示车厢数目,第二行是1-n的任意排列,表示n节车厢在主轨道右边的出站顺序。
【输出】如果调度可以完成,输出Yes,否则输出No
例如:
【输入】
5
3 4 1 5 2
【输出】
5 Yes//序列长度 判断结果
【输入】
3
3 2 1
【输出】
3 No //序列长度 判断结果

#include <iostream>
#include <stdio.h>
#define maxlen 150
#define len 51
using namespace std;

class CirQueue
{
public:
    CirQueue();
    bool Empty()const;
    bool Full()const;
    void serve();
    void append(int item);
    void retrive(int &item)const;
private:
    int cnt;//cnt元素个数
    int Front,rear;
    int entry[maxlen];
};

int main()
{
    CirQueue A;
    int n,i,duishou,temp = 1,flag = 0;
    int &a = duishou;
    cin >> n;
    int num[len];
    for(i=0; i<n; i++){
        getchar();
        cin >> num[i];
    }

    i=0;
    while(1){
        if(temp <= n){
           if(temp < num[i]){
               A.append(temp);
               temp++;
               continue;
           }
           else if(temp == num[i]){
               i++;
               temp++;
               continue;
           }
           else{
               A.retrive(a);
               if(duishou == num[i]){
                   i++;
                   A.serve();
                   continue;
               }
               else{
                   flag = 0;
                   break;
               }
           }
        }
        else{
            while(!A.Empty()){
                   A.retrive(a);
                   if(duishou == num[i]){
                       i++;
                       A.serve();
                       continue;
                   }
                   else{
                       flag = 1;
                       break;
                   }
            }
            break;
        }
    }
    if(flag) cout <<n <<" No";
    else cout <<n <<" Yes";
    return 0;
}

CirQueue::CirQueue()
{
    cnt = 0;
    rear = maxlen-1;
    Front = 0;
}

bool CirQueue::Empty()const
{
    bool outcome = false;
    if(cnt == 0) outcome = true;
    return outcome;
}

bool CirQueue::Full()const
{
    bool outcome = true;
    if(cnt < maxlen ) outcome = false;
    return outcome;
}

void CirQueue::append(int item)
{
    if(!Full()){
        cnt++;
        rear = ((rear+1) == maxlen)? 0: (rear+1);
        entry[rear] = item;
    }
}

void CirQueue::serve()
{
    if(!Empty()){
        cnt--;
        Front = (Front+1) == maxlen? 0: (Front+1);
    }
}

void CirQueue::retrive(int &item)const
{
    if(!Empty()) item = entry[Front];
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值