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;
}