DLUT-ISE 2020数据结构上机题记录

数据结构1

第一次上机

1.1 顺序表

/*1.1 顺序表

	bool Insert(const int p, const T value);        //1.1-b 在位置p插入元素value,表的长度增加1
	bool Delete(const int p);                       //1.1-d 删除位置p处的元素,表的长度减1
	int GetPos(const T x);					    	//1.1-c 返回值为x的元素的位置

*/
#include <iostream>
using namespace std;

#pragma once
template <class T>
class List {
   
public:
    void Clear(); //置空线性表
    bool IsEmpty(); //线性表为空时,返回true
    bool Append(const T value); //在表尾添加元素value,表的长度增加1
    bool Insert(const int p, const T value); //在位置p插入元素value,表的长度增加1
    bool Delete(const int p); //删除位置p处的元素,表的长度减1
    int GetPos(const T x); //把值为x的元素的位置返回到变量p中
};

template <class T> //线性表的元素类型为T
class ArrayList : public List<T> //定义顺序表ArrayList
{
   
public: //顺序表的运算集
    ArrayList(const int size) //创建顺序表,表长为最大长度
    {
   
        maxSize = size;
        arrayList = new T[maxSize];
        curLen = 0;
        position = 0;
    }
    ~ArrayList() //析构函数,消除ArrayList的实例
    {
   
        delete[] arrayList;
    }
    void clear() //清空顺序表
    {
   
        delete[] arrayList;
        curLen = 0;
        position = 0;
        arrayList = new T[maxSize];
    }

    int Length(); //顺序表的长度
    bool Append(const T value); //在表尾添加元素value,表的长度增加1

    bool Insert(const int p, const T value); //1.1-b 在位置p插入元素value,表的长度增加1
    bool Delete(const int p); //1.1-d 删除位置p处的元素,表的长度减1
    int GetPos(const T x); //1.1-c 返回值为x的元素的位置
    void PrintArray(); //输出顺序表内容
private:
    T* arrayList; //存储顺序表的实例
    int maxSize; //顺序表实例的最大长度
    int curLen; //顺序表实例的当前长度
    int position; //当前处理位置
};

template <class T>
int ArrayList<T>::Length()
{
   
    return curLen;
}

//在表尾添加元素value,表的长度增加1
template <class T>
bool ArrayList<T>::Append(const T value)
{
   
    if (curLen >= maxSize) //检查顺序表是否溢出
    {
   
        cout << "The List is overflow" << endl;
        return false;
    }

    arrayList[curLen] = value; //表尾处插入新元素
    curLen++; //表的实际长度增加1
    return true;
}

/*
TODO:1.1-b 在位置p插入元素value,表的长度增加1,p为要插入的位置下标值。比如:p=0,表示在顺序表的表头插入元素。
返回值说明:插入成功,返回true,否则返回false
注意事项:1)检查顺序表是否溢出,若溢出,则打印cout << "The List is overflow" << endl;返回false
          2)检查插入位置是否合法,若不合法,则cout << "Insertion point is illegal" << endl; 返回false
*/
template <class T>
bool ArrayList<T>::Insert(const int p, const T value)
{
   
    if (curLen >= maxSize){
                //检查溢出
        cout << "The List is overflow" << endl;
        return false;
    }
    if (p < 0||p > maxSize){
   
        cout << "Insertion point is illegal" << endl;
        return false;
    }
    for(int i = curLen;i > p;i--){
   
        arrayList[i] = arrayList[i-1];
    }
    arrayList[p] = value;
    curLen++;
    return true;
}

/*
TODO:1.1-d 删除位置p处的元素,表的长度减1,p为元素所在的下标值
返回值说明:删除成功,返回true,否则返回false
注意事项:1)如果顺序表中没有元素了,则打印cout << "No element to delete" << endl;并返回false
          2)如果删除的位置p非法,即p位置处无元素,则打印cout << "Deletion is illegal" << endl;并返回false
*/
template <class T>
bool ArrayList<T>::Delete(const int p)
{
   
    if(curLen <= 0){
   
        cout << "No element to delete" << endl;
        return false;
    }
    if(p < 0||p > curLen-1){
   
        cout << "Deletion is illegal" << endl;
        return false;
    }
    for(int i = p;i < curLen - 1;i++){
   
        arrayList[i] = arrayList[i+1];
    }
    curLen--;
    return true;
}

/*
TODO:1.1-c 返回值顺序表中第一个值为x的结点位置下标
返回值说明:如果在顺序表中从头到尾找到x元素,则立刻返回x元素所在的位置下标。即:假如x在顺序表中第一个位置,则返回0,以此类推
            如果找不到x元素,则返回-1
*/
template <class T>
int ArrayList<T>::GetPos(const T x)
{
   
    for(int i = 0;i < curLen;i++){
   
        if(arrayList[i] == x){
   
            return i;
        }
    }
    return -1;
}

//输出顺序表内容
template <class T>
void ArrayList<T>::PrintArray()
{
   
    for (int i = 0; i < curLen; i++) {
   
        cout << arrayList[i] << " ";
    }
    cout << endl;
}
int main()
{
   
    int maxsize, pos0, pos1, value0, value1;
    cin >> maxsize >> pos0 >> pos1 >> value0 >> value1;
    ArrayList<int> arr(maxsize);
    int p;
    for (int i = 0; i < 5; i++) {
   
        arr.Append(i);
    }
    arr.PrintArray();
    arr.Insert(pos0, value0); //位置pos0处插入value0
    arr.PrintArray();
    arr.Delete(pos1); //删除位置pos1处的元素
    arr.PrintArray();
    p = arr.GetPos(value1); //获得值为value1的结点位置
    cout << p << endl;
    return 0;
}

1.2 单链表倒置

/*	1.2单链表倒置
	课后习题1.8-b
	b.	给定一个不带头结点的单链表,写出将链表倒置的算法
		Node* Reverse(Node* first)
*/
#include <iostream>
using namespace std;
struct Node {
   
    Node(int x)
    {
   
        value = x;
        next = NULL;
    }
    int value;
    Node* next;
};

/*
TODO:链表倒置的算法
 */
Node* Reverse(Node* first)
{
   
    Node *p,*q;
    p = first;
    q = NULL;
    Node *temp;

    while(p != NULL){
   
        temp = p;
        p = p->next;
        temp->next = q;
        q = temp;
    }
}
void print(Node* node)
{
   
    while (NULL != node) {
   
        cout << node->value << " ";
        node = node->next;
    }
}
int main()
{
   
    int iNum;
    cin >> iNum;
    Node* a = NULL;
    Node* pTemp;

    for (int i = 0; i < iNum; i++) {
   
        int tmp;
        cin >> tmp;
        if (i == 0) {
   
            a = new Node(tmp);
            pTemp = a;
        } else {
   
            pTemp->next = new Node(tmp);
            pTemp = pTemp->next;
        }
    }

    cout << "倒置前为:";
    print(a);
    cout << endl;
    Node* r = Reverse(a);
    cout << "倒置后为:";
    print(r);
    cout << endl;
    return 0;
}

1.3 将两个有序链表合并成一个非递减有序的单链表

/*	1.3将两个有序链表合并成一个非递减有序的单链表
	课后习题1.8-d

	d.	设ha和hb分别是两个带头结点的非递减有序单链表的表头指针,试设计一个算法,
		将这两个有序链表合并成一个非递减有序的单链表。要求结果链表仍使用原来两个链表的存储空间,
		不另外占用其他的存储空间。表中允许有重复的数据。

		Node* Merge(Node* a, Node* b)

*/
#include <iostream>
using namespace std;
const int MinNumber = -1000000;
struct Node {
   
    Node(int x)
    {
   
        value = x;
        next = NULL;
    }
    int value;
    Node* next;
};

/*
TODO:链表连接,将链表a和链表b进行连接合并,连接合并后结果链表仍使用原来两个链表的存储空间,
不另外占用其他的存储空间,且合并后的是一个非递减有序的单链表。
返回值说明:返回合并后的非递减有序单链表
*/
Node* Merge(Node* a, Node* b)
{
      Node *p=NULL;
    Node *q=NULL;// q是新头
    if(a->value < b->value){
   
        p = a;
        q = a;
        a = a->next;
    }
    else{
   
        p = b;
        q = b;
        b = b->next;
    }
    while(a && b){
   
        if(a->value <= b->value){
   

            p->next = a;
            a = a->next;

        }
        else{
   

            p->next = b;
            b = b->next;

        }
        p = p->next;
    }
    p->next = a? a : b;
    return q;
}
void print(Node* pNode)
{
   
    while (pNode != NULL) {
   
        cout << pNode->value << " ";
        pNode = pNode->next;
    }
    cout << endl;
}

Node* init()
{
   
    int count;
    cin >> count;
    Node *p = NULL, *q;
    for (int i = 0; i < count; i++) {
   
        int iValue;
        cin >> iValue;
        if (NULL == p) {
   
            p = new Node(iValue);
            q = p;
        } else {
   
            q->next = new Node(iValue);
            q = q->next;
        }
    }
    return p;
}

int main()
{
   
    Node* ha = init();
    Node* hb = init();
    cout << "合并前链表1为:";
    print(ha);
    cout << "合并前链表2为:";
    print(hb);
    Node* head = Merge(ha, hb);
    cout << "合并后的单链表为:";
    print(head);
    return 0;
}

1.4 顺序栈

/*1.4 顺序栈

	bool Push(const T item)		//1.3-a. 入栈操作,并判断栈是否为满
	bool Pop(T& item)			//1.3-b 出栈操作,并判断栈是否为空,返回栈顶元素
	bool Top(T& item)			//1.3-c 读取栈顶元素,但不删除,判断栈是否为空

*/
#include <iostream>
using namespace std;

template <class T>
class Stack {
   
public:
    void Clear();
    bool Push(const T item);
    bool Pop(T& item);
    bool Top(T& item);
    bool IsEmpty();
    bool IsFull;
};

template <class T>
class ArrayStack : public Stack<T> {
   
public:
    ArrayStack(int size)
    {
   
        maxSize = size;
        top = -1;
        st = new T[maxSize];
    }
    ArrayStack()
    {
   
        top = -1;
    }
    ~ArrayStack()
    {
   
        delete[] st;
    }
    void Clear()
    {
   
        top = -1;
    }
    /*
	TODO:1.3-a. 入栈操作,并判断栈是否为满,若栈已满,则打印cout << "栈满溢出" << endl;返回false。否则将item入栈,返回true
	返回值说明:成功入栈,返回true,否则返回false。
	 */
    bool Push(const T item)
    {
   
        if(top == maxSize - 1){
   
            cout << "栈满溢出" << endl;
            return false;
        }
        else{
   
            st[++top] = item;
            return true;
        }
    }
    /*
	TODO:1.3-b 出栈操作,并判断栈是否为空,若为空,则打印cout << "栈为空,不能进行删除操作" << endl;返回false。
	否则,将栈顶元素的值取出来赋值给item,进行出栈操作,返回true
	返回值说明:如果出栈成功,返回true,否则返回false。
	 */
    bool Pop(T& item)
    {
   
        if(top == -1){
   
            cout << "栈为空,不能进行删除操作" << endl;
            return false;
        }
        else{
   
            item = st[top--];
            return true;
        }

    }
    /*
	TODO:1.3-c 读取栈顶元素,但不删除,判断栈是否为空,若为空,则打印cout << "栈为空,不能读取栈顶元素" << endl;返回false
	否则,将栈顶元素取出,并赋值给item,返回true。
	返回值说明:成功读取栈顶元素,返回true,否则返回false。
	 */
    bool Top(T& item)
    {
   
        if(top == -1){
   
            cout << "栈为空,不能读取栈顶元素" << endl;
            return false;
        }
        else{
   
            item = st[top];
            return true;
        }
    }

private:
    int maxSize; //栈中最多保存的元素个数
    int top; //指向栈顶,初始化为-1,入栈时top+1,出栈时top-1
    T* st; //栈
};

int main()
{
   
    int maxsize, loop_num, temp;
    cin >> maxsize >> loop_num >> temp;

    ArrayStack<int> as(maxsize);
    for (int i = 1; i < loop_num; i++) {
   
        as.Push(i);
    }
    as.Push(temp);
    cout << "入栈:" << temp << endl;
    as.Pop(temp);
    cout << "出栈:" << temp << endl;
    as.Top(temp);
    cout << "读取栈顶元素:" << temp << endl;
    return 0;
}


1.5 顺序队列

/*1.5 顺序队列

	bool EnQueue(const T item)	//1.5-a.	入队操作,判断队列是否为满
	bool DeQueue(T& item)		//1.5-b.	返回队头元素,并删除该元素,判断队列是否为空
	bool GetFront(T& item)		//1.5-c.	返回队头元素,但不删除,判断队列是否为空】

*/
#include <iostream>
using namespace std;

template <class T>
class ArrayQueue {
   
private:
    int maxSize; //队列最大容量
    int front;
    int rear;
    int* queue;

public:
    ArrayQueue(int size)
    {
   
        maxSize = size + 1;
        queue = new T[maxSize];
        front = rear = 0;
    }
    ~ArrayQueue()
    {
   
        delete[] queue;
    }

    void Clear()
    {
   
        front = rear;
    }

    /*
	TODO:1.5-a.入队操作,判断队列是否为满,如果队列已满,则输出打印cout << "队列已满,溢出" << endl;,返回false。
	否则,将值item进行入队操作。并返回true
	返回值说明:入队成功,返回true,否则返回false
	 */
    bool EnQueue(const T item)
    {
   
        if(this->IsFull()){
   
            return false;
        }
        queue[rear] = item;
        rear = (rear + 1) % maxSize;
        return true;
    }
    /*
	TODO:1.5-b.返回队头元素,并删除该元素,判断队列是否为空
	如果队列为空,则输出打印cout << "队列为空" << endl;并返回false。
	否则将队列头元素取出并赋值给item变量并删除该元素,返回true
	返回值说明:成功获取队头元素返回true,否则返回false
	 */
    bool DeQueue(T& item)
    {
   
        if(this->IsEmpty()){
   
            return false;
        }
        item = queue[front];
        front = (front + 1) % maxSize;
        return true;
    }
    /*
	TODO:1.5-c.	返回队头元素,但不删除,判断队列是否为空
	如果队列为空,则打印cout << "队列为空" << endl;并返回false。
	否则取出队头元素赋值给item,返回true。
	返回值说明:成功获取队头元素,返回true,否则返回false
	 */
    bool GetFront(T& item)
    {
   
        if(this->IsEmpty()){
   
            return false;
        }
        item = this->queue[this->front];
        return true;
    }

    bool IsEmpty()
    {
   
        if (front == rear) {
   
            cout << "队列为空" << endl;
            return true;
        } else {
   
            return false;
        }
    }
    bool IsFull()
    {
   
        if ((rear + 1) % maxSize == front) {
   
            cout << "队列已满,溢出" << endl;
            return true;
        } else {
   
            return false;
        }
    }
};

int main()
{
   
    int maxsize = 0, iNum = 0, temp1 = 0, temp2 = 0, temp3 = 0;
    cin >> maxsize >> iNum >> temp1;
    ArrayQueue<int> aq(maxsize);
    for (int i = 0; i < iNum; i++) {
   
        aq.EnQueue(i * 3);
    }
    aq.EnQueue(temp1);
    aq.DeQueue(temp2);
    cout << "出队:" << temp2 << endl;
    aq.GetFront(temp3);
    cout << "读取队头元素:" << temp3 << endl;
    return 0;
}


第二次上机

2.1 采用顺序栈判断表达式中的括号是否正确配对

/*	2.1采用顺序栈判断表达式中的括号是否正确配对
	课后习题1.8-h

	h.	假设表达式中允许包含3中括号:圆括号、方括号和大括号。
		设计一个算法采用顺序栈判断表达式中的括号是否正确配对。
		void Bracketmatch(const char* c)

*/
#include <cstring>
#include <iostream>
#include <string.h>
using namespace std;

class stack {
   
private:
    int maxsize;
    int top;
    char* st;

public:
    stack(int size)
    {
   
        maxsize = size;
        top = -1;
        st = new char[maxsize];
    }

    void push(char item)
    {
   
        st[++top] = item;
    }

    void pop()
    {
   
        top--;
    }

    bool empty()
    {
   
        return top == -1;// 是空返回true 非空返回false
    }
};
/*
TODO:计一个算法采用顺序栈判断表达式c中的括号是否正确配对。
返回值说明:返回长度为3个字符的字符串,
第1个字符表示()的匹配情况。
第2个字符表示[]的匹配情况
第3个字符表示{}的匹配情况。
如果匹配,则对应的字符设置为'1',否则设置为'0'。
比如:返回值为"110",表示:()匹配,[]匹配,{}不匹配
 */
 //     {1*[3*2+(2-1)}
char* Bracketmatch(const char* c) //括号匹配
{
      
    char result[] = "111";
    int len = strlen(c);
    stack small(len);
    stack mid(len);
    stack larg(len);
    for(int i = 0;c[i] != '\0';i++)
    {
   
        if(c[i] == '{'){
   
            larg.push(c[i]);
        }
        if(c[i] == '['){
   
            mid.push(c[i]);
        }
        if(c[i] == '('){
   
            small.push(c[i]);
        }
        if(c[i] == ')'){
   
            if(!small.empty()){
   
                small.pop();
            }
            else{
   
                result[0] = '0';
            }
        }
        if(c[i] == ']'){
   
            if(!mid.empty()){
   
                mid.pop();
            }
            else{
   
                result[1] = '0';
            }
        }
        if(c[i] == '}'){
   
            if(!larg.empty()){
   
                larg.pop();
            }
            else{
   
                result[2] = '0';
            }
        }
    }
    if(!small.empty()){
   
        result[0] = '0';
    }
    if(!mid.empty()){
   
        result[1] = '0';
    }
    if(!larg.empty()){
   
        result[2] = '0';
    }
    char *p = new char[len+1];
    strcpy(p,result);
    return p;
}
void printResult(char* p)
{
   
    if (NULL != p) {
   
        if (p[0] == '1') {
   
            cout << "()匹配" << endl;
        } else {
   
            cout << "()不匹配" << endl;
        }

        if (p[1] == '1') {
   
            cout << "[]匹配" << endl;
        } else {
   
            cout << "[]不匹配" << endl;
        }

        if (p[2] == '1') {
   
            cout << "{}匹配" << endl;
        } else {
   
            cout << "{}不匹配" << endl;
        }
    }
}
int main()
{
   

    string s;
    getline(cin, s);
    cout << s << endl;
    char* result = Bracketmatch(s.c_str());
    printResult(result);
    delete result;
    return 0;
}

2.2 链式栈-中缀表达式

/**	2.2链式栈-中缀表达式
	1.4-d,e 计算器:中缀表达式转换为后缀,并计算

	void infix_to_suffix();   //1.4-e  将中缀表达式转换为后缀表达
	void cal_suffix();        //1.4-d.	计算中缀表达式的值

**/
#include <cstdlib>
#include <iostream>
#include <string.h>

using namespace std;

template <class T>
class stack {
   
	private:
		int top; //栈顶
		int maxtop; //最大的栈顶值
		T* st; //堆栈元素数组
	public:
		stack(int maxstacksize = 10) {
   
			maxtop = maxstacksize - 1;
			st = new T[maxstacksize];
			top = -1;
		}
		~stack() {
   
			delete[] st;
		}
		bool isfull() {
   
			return top == maxtop;
		}
		bool isempty() {
   
			return top == -1;//是空,返回true
		}
		bool add(const T& x) {
   
			if (isfull()) {
   
				cout << "no memory" << endl;
				return false;
			}
			top++;
			st[top] = x;
			return true;
		}
		T del() {
   
			if (isempty()) {
   
				cerr << "no element" << endl;
			}
			T x;
			x = st[top];
			top--;
			return x;
		}
		T returntop() {
   
			return st[top];
		}
		void clear() {
   
			top = -1;
		}
		void output() {
   
			if (isempty()) {
   
				cout << "栈是空的" << endl;
			} else {
   
				for (int i = 0; i <= top; i++) {
   
					cout << st[i] << '\t';
				}
				cout << endl;
			}
		}
};

class Calculator {
   
	public:
		string infix; //中缀表达式
		string postfix; //后缀表达式
		stack<double> poststack; //后缀栈
		Calculator(string str);
		~Calculator() {
   
			poststack.clear();
		}
		void infix_to_suffix(); //1.4-e  将中缀表达式转换为后缀表达
		int inStack(char ch); //栈内优先级
		int outStack(char ch); //栈外优先级数
		void cal_suffix(); //1.4-d.	计算中缀表达式的值
		void print();
		bool Get_operands(double& left, double& right);
		bool isNumber(char ch);
		double returnnum(char* c, int n); //返回字符对应的数
		float toNum(char num_ch); //数值型字符转换成数字
		void cal(char ch); //根据操作符 去栈中去取两个元素计算
};
Calculator::Calculator(string str) {
   
	infix = str;
}

/*					2*(3+5)+7/1-4
TODO:1.4-e  将中缀表达式转换为后缀表达,假如中缀表达式为1+(2-3)*4+4/2,
则转换后为:1&2&3&-4&*+4&2&/+ [为了区分数字与数字,用&符号将数字进行隔开,当然也可自行选择其他方式来表达]
 */
void Calculator::infix_to_suffix() {
   
	int len = infix.length();
	for(int i = 0; i < len; i++) {
   
		if(isNumber(infix[i])){
   
			postfix += infix[i];
			postfix += '&';
		}
		else if(infix[i] == '('){
   
			poststack.add(infix[i]);
		}
		else if(infix[i] == ')'){
   
			while(!poststack.isempty() && poststack.returntop() != '('){
   
				char t = poststack.del();
				postfix += t;
			}
			poststack.del();
		}
		else{
   
			while(!poststack.isempty() && poststack.returntop() != '(' && outStack(infix[i]) <= inStack(poststack.returntop())){
   
				char temp = poststack.del();
				postfix += temp;
			}
			poststack.add(infix[i]);
		}
	}
	while(!poststack.isempty()){
   
		char temp1 = poststack.del();
		postfix += temp1;
	}
}
/*
TODO: 1.4-d.计算中缀表达式的值,比如:假如中缀表达式为1+(2-3)*4+4/2,则根据四则混合运算优先级计算,它的结果为-1.
如果输入的中缀表达式非法,则打印cout << "重新输入 并检查表达式的合法性" << endl;,然后exit(0)结束执行。
*/
void Calculator::cal_suffix() {
   
	infix_to_suffix(); //将中缀表达式转换为后缀表达式
	// 后缀栈要用类里定义的,才能调用下面的函数
	//			要跳过&!!! 模板栈能存任意类型,但这里取两个值的时候必须是double才能取,需要转换类型 
	int len = postfix.length();
	for(int i = 0; i < len; i++) {
   
		if(postfix[i] == '&') {
   
			continue;
		}
		else if(isNumber(postfix[i])) {
   
			poststack.add(toNum(postfix[i]));
		}
		else if(postfix[i] == '+' || postfix[i] == '-' || postfix[i] == '*' || postfix[i] == '/') {
   
			cal(postfix[i]);
		}
		else{
   
			cout << "重新输入 并检查表达式的合法性" << endl;
			exit(0);
		}
	}

}

bool Calculator::Get_operands(double& left, double& right) {
   
	if (poststack.isempty()) {
   
		cout << "缺少右操作数" << endl;
		return false;
	}
	right = poststack.del(); //取右操作数
	if (poststack.isempty()) {
   
		cout << "缺少左操作数" << endl;
		return false;
	}
	left = poststack.del(); //取出左操作数
	return true; //返回true
}
double Calculator::returnnum(char* c, int n) {
    //返回字符对应的数,n表示个十百千位
	int l = n;
	double num = 0;
	double m = 1;
	for (int i = l - 1; i >= 0; i--) {
   
		num += toNum(c[i]) * m;
		m *= 10;
	}
	return num;
}

int Calculator::inStack(char c) {
   
	switch (c) {
   
		case '#':
			return 0;
			break;
		case '(':
			return 1;
			break;
		case '*':
		case '/':
		case '%':
			return 5;
			break;
		case '+':
		case '-':
			return 3;
			break;
		case ')':
			return 6;
			break;
	}
}
//返回操作符的栈外优先级
int Calculator::outStack(char c) {
   
	switch (c) {
   
		case '#':
			return 0;
			break;
		case '(':
			return 6;
			break;
		case '*':
		case '/':
		case '%':
			return 4;
			break;
		case '+':
		case '-':
			return 2;
			break;
		case ')':
			return 1;
			break;
	}
}
//判断是否为操作数
bool Calculator::isNumber(char ch) {
   
	if (48 <= ch && ch <= 57)
		return true;
	else
		return false;
}

//数值型字符转换为数字
float Calculator::toNum(char num_ch) {
   
	switch (num_ch) {
   
		case '0':
			return 0;
			break;
		case '1':
			return 1;
			break;
		case '2':
			return 2;
			break;
		case '3':
			return 3;
			break;
		case '4':
			return 4;
			break;
		case '5':
			return 5;
			break;
		case '6':
			return 6;
			break;
		case '7':
			return 7;
			break;
		case '8':
			return 8;
			break;
		case '9':
			return 9;
			break;
	}
}
//根据操作符 去栈中去取两个元素计算
void Calculator::cal(char cp) {
   
	double left, right, value;
	if (Get_operands(left, right)) {
   
		switch (cp) {
   
			case '+': {
   
				value = left + right;
				poststack.add(value); //相加后结果压栈
				break;
			}
			case '-': {
   
				value = left - right;
				poststack.add(value); //相减 压栈
				break;
			}
			case '*': {
   
				value = left * right;
				poststack.add(value); //相乘 压栈
				break;
			}
			case '/':
				if (right == 0) {
   
					cout << "/ 操作符 右操作数为0" << endl;
					exit(1);
				} else {
   
					value = left / right;
					poststack.add(value); //相除 压栈
				}
				break;
		}
	}
}
//保留并输出最后结果
void Calculator::print() {
   
	cout << "表达式计算结果:" << endl;
	cout << poststack.returntop() << endl;
}
int main() {
   
	string str;
	cout << "输入一个中缀表达式:" << endl;
	cin >> str;
	Calculator calculator(str);
	calculator.cal_suffix();
	calculator.print(); //显示结果
	return 0;
}

2.3 串匹配KMP算法

//2.3串匹配KMP算法
#include <iostream>
#include <string.h>

using namespace std;

/*
 * TODO:求模式T的next值
 * 功能描述:使用蛮力法求模式T的next值
 * 参数说明:T[]: 模式T
 *          next[]: 任意两个数组
 * 返回值说明:空
*/
void GetNext(char T[], int next[])	//书上的算法 
{
   
	int len = strlen(T);
	next[0] = 0;
	for(int i = 1;i < len;i++){
   
		int j = next[i-1];
		while(j > 0 && T[i] != T[j]){
   
			j = next[j-1];
		}
		if(T[i] == T[j]){
   
			next[i] = j + 1;
		}
		else{
   
			next[i] = 0;
		}
	}
}

/*
 * TODO:串匹配KMP算法
 * 功能描述:输入主串S,以及模式T,返回T在S中的位置, 使用串匹配KMP算法求解该问题。
            调用GetNext方法求解时假定模式最长为80个字符。
 * 参数说明:S[]: 主串S
 *           T[]: 模式T
 * 返回值说明:返回匹配的开始位置(下标+1)
 * 举例说明:查找模式T:abcacc在主串S:abcabcabcaccb中的位置是:7
*/
int KMP(char S[],char T[])
{
   
	int i = 0;
	int j = 0;		
	int next[80];
    GetNext(T,next);	//书上差不多 
   	for(i = 0;i < strlen(S); i++){
   
   		while(T[j] != S[i] && j > 0){
   
   			j = next[j-1];
		}
		if(S[i] == T[j]){
   
			j++;
		}
		if(j == strlen(T)){
   
			return(i-j+2);	
		}
	}
	return 0;
}

int main()
{
   

    const int size = 20;
    char S[size];
    char T[size];
    //串匹配BF算法
    //输入: 主串S, 模式T
    cout<<"请输入主串S:"<<endl;
    cin>>S;
    cin.get();
    cout<<"请输入查找模式T:"<<endl;
    cin>>T;
    cin.get();
    //串匹配KMP算法
    //输入: 主串S, 模式T
    int index = KMP(S,T);
    //输出: T在S中的位置
    for (int i = 1; i < index; i++)
        cout<<" ";
    cout<<T<<"在"<<endl;
    cout<<S<<"中的位置是:"<<index<<endl;
    return 0;
}

第三次上机

队列:银行叫号系统的实现

/* 队列:银行叫号系统的实现

具体要求请见教材2.7.2 队列:银行叫号系统的实现 p69 (PDF中是在54页) 本次上机代码需要提交到华为云。

编写一个程序模拟银行取号系统,该程序只是模拟了取号排队的功能,

本模拟系统的最终目标是:
实现叫号机的基本功能,即用户到达后可以叫号,工作人员登录进入系统后可以对用户进行办理业务。
*/
// 业务处理时间为4s 用户入队间隔为2s
#include <bits/stdc++.h>
using namespace std;
int gid = 1;
class User
{
   
public:
    int id;
    bool isWait = true;
    int ArriveTime;
    char type;
};
class BankWindow
{
   
public:
    bool isBusy = false;
    int id;
    char type;
    int timei = 0; //用来记录服务时长,=2时重置为0恢复空闲。
    User client;
};
class Simulater
{
   
private: //若用for循环把该矩阵随机赋值就是随机生成用户了吧
    int cMatrix[7][3] = {
   {
   3, 1, 1}, {
   5, 0, 0}, {
   0, 0, 0}, {
   5, 1, 0}, {
   0, 0, 0}, {
   0, 0, 0}, {
   0, 0, 0}};
    BankWindow n[3], v, o;
    queue<User> NormalUserQueue;
    queue<User> VIPUserQueue;
    queue<User> OfficialUserQueue;

public:
    void setWindow();                    //1
    void simulateCustomerEnter(User &u); //1
    void simulateCallCustomer();         //1
    void Simulate();                     //1
    void printWindow();                  //1
};
// 以上类定义完了,开始实现各种函数?
void Simulater::simulateCu
  • 11
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值