【数据结构】实验四 栈与队列的应用(括号匹配与舞伴问题)

1、给定一个只包含括号(假设只包含‘(’和‘)’)的表达式,使用栈判断表达式中的括号是否匹配。
例如:(()(()))该式中括号匹配成功;((()())该式中括号匹配失败。
2、舞伴问题。假设周末舞会上,男士们和女士们进入舞厅时各自排成一队。跳舞开始时,依次从男队和女队的队首各出列一名配成一对舞伴。若两队人数不同,则较长的那队中未配对的人等待下一首舞曲。是写一算法模拟上述配对问题。
注意:使用队列实现上述问题。可以有所扩展,譬如舞厅大小有限,每次只允许几组人跳舞,跳完之后可以继续排队,等待下一个舞曲等。本题自由发挥,考虑不同需求等。

#include<iostream>
#define ElemType char
#define MAXSIZE 100
using namespace std;

typedef struct // 定义栈的结构体
{
	ElemType st[MAXSIZE]; // 存储栈内元素 最大长度为MAXSIZE
	int top; // 栈顶索引
}SqStack;

typedef struct // 跳舞者的个人信息
{
	char name[20]; // 姓名
	char sex; // 性别 F表示女性 M表示男性
}Person;

typedef struct // 定义队列的结构体
{
	Person *base; // 存储队列内元素 元素类型为Person
	int front; // 头指针 始终指向队列首元素
	int rear; // 尾指针 始终指向队列尾元素
}SqQueue;

void InitStack(SqStack &S)// 栈的初始化
{
	S.top = -1; // 将栈顶指针置为 -1
	cout << "栈的初始化成功!" << endl;
}

void InitQueue(SqQueue& Q)// 队列的初始化
{
	Q.base = new Person[MAXSIZE];
	if (!Q.base)
		exit(1);
	Q.front = Q.rear = 0; // 将队列头指针和尾指针置为0 此时队列为空
	cout << "队列的初始化成功!" << endl;
}

bool Pop(SqStack& S) // 判断栈顶元素是否为( 
{
	if (S.top == -1) // 前提:是否为空栈
	{
		return false;
	}
	else if (S.st[S.top] == '(') // 若栈顶元素为( 则弹出
	{
		S.top--; // 栈顶指针减一
		return true; // 本轮匹配成功
	}
	else
	{
		return false; // 本轮匹配失败
	}
}

bool Push(SqStack& S, ElemType e) // 向顺序栈S中添加元素e
{
	if (S.top == MAXSIZE) // 判断栈是否已满(S.top是否可以再自加)
	{
		cout << "栈满溢出!" << endl;
		return false;
	}
	else if (e == '(') // 栈没有满 判断是否继续添加元素
	{
		S.st[++S.top] = e; // 先让top指向下一个索引 再赋值
		return true;
	}
	else if (e == ')' && S.top != -1) // 栈没有满且没有空 判断是否弹栈
	{
		return Pop(S);
	}
	else if (e == ')')
	{
		S.st[++S.top] = e; // 先让top指向下一个索引 再赋值
		return false; 
	}
}

// 栈判断表达式中的括号是否匹配
void IfMatch()
{
	SqStack S; // 定义一个顺序栈
	InitStack(S); // 初始化顺序栈S
	cout << "请输入英文左右括号(结束输入请输入0)" << endl;
	char e; // 临时储存输入的括号
	do
	{
		cin >> e;
		if (e == '0') // 结束条件
			break;
	} while (Push(S, e));
	if (S.top == -1)
	{
		cout << "表达式中的括号是匹配的" << endl;
	}
	else
	{
		cout << "表达式中的括号不匹配!" << endl;
	}
}

void EnQueue(SqQueue& Q, Person e) // 在队尾插入元素 e
{
	if ((Q.rear + 1) % MAXSIZE == Q.front) // 队列已满
		return;
	Q.base[Q.rear] = e; // 尾指针始终指向队列尾元素的下一个元素
	Q.rear = (Q.rear + 1) % MAXSIZE; // 赋值完成后 尾指针加1
}

bool EmptyQueue(SqQueue Q) // 判断是否是空队列
{
	if (Q.front == Q.rear) // 空队列
	{
		return true;
	}
	else // 非空队列
	{
		return false;
	}
}

void DeQueue(SqQueue &Q ,Person &e) // 删除Q的队头元素,用e返回其值
{
	if (Q.front == Q.rear) // 判断是否队空
		return;
	e = Q.base[Q.front]; // 保存队头元素
	Q.front = (Q.front + 1) % MAXSIZE; // 队头指针加1
}

Person GetHead(SqQueue Q) // 返回Q的队头元素 不修改队头指针
{
	if (Q.front != Q.rear) // 判断队列是否非空
		return Q.base[Q.front]; // 返回队头元素的值 队头指针不变
}

void DanceQueue() // 舞伴问题函数
{
	SqQueue QFemale; // 定义男士队列
	SqQueue QMale; // 定义女士队列
	Person p; // 定义一个临时存储个人信息的变量
	InitQueue(QFemale); // 初始化队列
	InitQueue(QMale);
	int man, woman; // 定义两个参数 记录男女人数
	cout << "请输入男士一共有多少人:";
	cin >> man;
	cout << "请输入女士一共有多少人:";
	cin >> woman;
	// 在男士队列中插入元素
	for (int i = 1; i <= man; i++)
	{
		cout << "请输入第 " << i << " 个男士的信息" << endl;
		Person temp;
		cout << "姓名 >> ";
		cin >> temp.name;
		temp.sex = 'M'; // 性别为 男(M)
		EnQueue(QMale, temp); // 队尾插入第i个男士的信息 
	}
	// 在女士队列中插入元素
	for (int i = 1; i <= woman; i++)
	{
		cout << "请输入第 " << i << " 个女士的信息" << endl;
		Person temp;
		cout << "姓名 >> ";
		cin >> temp.name;
		temp.sex = 'F'; // 性别为 女(F)
		EnQueue(QFemale, temp); // 队尾插入第i个女士的信息 
	}
	while (!EmptyQueue(QMale)&&!EmptyQueue(QFemale)) // 依次输出男女舞伴的姓名
	{
		DeQueue(QFemale, p); // 队首女士出队
		cout << p.name << endl; // 输出出队女士姓名
		DeQueue(QMale, p); // 队首男士出队
		cout << p.name << endl; // 输出出队男士姓名
	}
	if (!EmptyQueue(QFemale)) // 若女士队列非空,输出队头女士的姓名
	{
		p = GetHead(QFemale); // 取女士队头
		cout << "下一个舞曲等待的是女士 >> 其姓名为:" << p.name << endl;
	}
	else if (!EmptyQueue(QMale)) // 若男士队列非空,输出队头男士的姓名
	{
		p = GetHead(QMale); // 取男士队头
		cout << "下一个舞曲等待的是男士 >> 其姓名为:" << p.name << endl;
	}
	else // 男女士恰好匹配完成
	{
		cout << "男士与女士人数相同!" << endl;
	}
}

void ShowList() // 展示选项菜单函数
{
	cout << ">> 欢迎来到实验四测试系统!" << endl;
	cout << "****************************************" << endl;
	cout << "**     ---------系统选项---------     **" << endl;
	cout << "**     1.判断表达式中的括号是否匹配   **" << endl;
	cout << "**     2.舞伴问题                     **" << endl;
	cout << "**     0.结束程序                     **" << endl;
	cout << "****************************************" << endl;
}

int main()
{
	while (1)
	{
		ShowList(); // 展示选项菜单
		int select; // 临时储存选项
		cout << "请输入您的选项 >> ";
		cin >> select;
		if (select == 0) // 判断结束条件
		{
			break;
		}
		switch (select)
		{
		case 1:
			IfMatch(); // 判断表达式中的括号是否匹配
			break;
		case 2:
			DanceQueue(); // 舞伴问题
			break;
		}
		system("pause"); // 暂停操作
		system("cls"); // 清屏操作
	}
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张鱼·小丸子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值