实验内容
1.进制转换
要求:用顺序栈或链栈实现将一个十进制数N转换为r(r=2,8,16)进制数。
2.括号匹配的检验
要求:借助顺序栈或链栈判断输入的表达式中括号是否匹配(包括()、[]、{}),如果不匹配输出原因。
3.中缀表达式求值
要求:借助顺序栈或链栈实现表达式求值
4.后缀表达式求值
输入一个中缀表达式,利用栈及运算符间的优先关系将中缀表达式转换为后缀表达式,然后只需要一个操作数栈即可对后缀表达式求值得到结果。
5.舞伴问题
假设在周末舞会上,男士们和女士们进入舞厅时,各自排成一队。跳舞开始时,依次从男队和女队的队头上各出一人配成舞伴。若两队初始人数不相同,则较长的那一队中未配对者等待下一轮舞曲,算法输出此队列中等待者的人数及排在队头的等待者的名字,他(或她)将是下一轮舞曲开始时第一个可获得舞伴的人。要求用循环队列或链队列模拟上述舞伴配对问题。
要求:从1-5题目中任选一个。
设计思想描述
选择的是第4个后缀表达式求值,主要有以下设计
1.运算符优先级的判断:读入的运算符使用switch和case进行判断优先级,运算符为“(”,则返回0,运算符为“+”“-”,则返回1,运算符为“*”“/”,则返回2,否则输入错误。
2.中缀表达式转换为后缀表达式:设置string后缀表达式为空,循环读入表达式并判断每个字符,若为数字则直接接入后缀表达式;若为左括号,则直接入栈;若为右括号,则一直出栈接入后缀表达式,直到遇到左括号停止出栈。若为运算符,如果栈为空,则直接入栈,如果运算符的优先级不同,则先进行比较。若优先级大于栈顶元素的优先级,则直接入栈;若优先级小于等于栈顶元素优先级,则不断比较并出栈直到栈为空。若读入结束后栈不为空,则不断出栈接入后缀表达式直到栈为空,最后返回转换后的后缀表达式。
3.计算后缀表达式:创建一个操作数栈,循环读入后缀表达式,如果是数字则入栈,如果是运算符则出栈两次,两个数字根据读入的运算符进行计算,再将计算结果入栈,最后栈中的元素即为运算结果。
实验结果
源代码
#include<iostream>
using namespace std;
const int MAX = 32;
class Stack
{
public:
Stack()
{Top = -1;}
void push(int value)//入栈
{
if (Top < MAX - 1)
{
Top++;
array[Top] = value;
}
}
void pop()//出栈
{
if (!empty())
Top--;
}
int top()//获取栈顶元素
{
if (!empty())
return array[Top];
}
bool empty()//栈是否空
{
if (Top == -1)
return true;
else
return false;
}
private:
int array[MAX];
int Top;
};
//运算符的优先级
int value(char a)
{
switch (a)
{
case '(':
return 0;
break;
case '+':
case '-':
return 1;
break;
case '*':
case '/':
return 2;
break;
default:
cout << "输入错误" << endl;
break;
}
}
//计算
double jisuan(double x, double y, char a)
{
switch (a)
{
case '+':
return x + y;
break;
case '-':
return x - y;
break;
case '*':
return x * y;
break;
case '/':
if (!y)
cout << "除数不能为0" << endl;
else
return x / y;
break;
default:
cout << "输入错误" << endl;
break;
}
}
//将中缀表达式转化成后缀表达式
string change(string str)
{
string changed = "";
Stack s;
int flag = 1;//用于判断-是负号还是减号
for (int i = 0; i < str.length(); i++)
{
if (str[i] >= '0' && str[i] <= '9')//为数字,则直接接到后缀表达式后面
{
changed += str[i];
flag = 0;
}
else if (str[i] == '(')//为左括号,直接压入栈
s.push(str[i]);
else if (str[i] == ')')//为右括号,一直出栈接入后缀表达式
{
while (s.top() != '(')
{
changed += ' ';
changed += s.top();
s.pop();
if (s.empty())
break;
}
s.pop();
}
else
{
if (flag)
{
changed += str[i];
flag = 0;
}
else
{
changed += ' ';
if (s.empty())
s.push(str[i]);//栈空,则直接入栈
else if (value(str[i]) > value(s.top()))//优先级大于栈顶,直接入栈
s.push(str[i]);
else//优先级小于等于前一个,则不断比较并出栈
{
while (value(str[i]) <= value(s.top()))
{
changed += s.top();
changed += ' ';
s.pop();
if (s.empty())
break;
}
s.push(str[i]);
}
flag = 1;
}
}
}
while (!s.empty())//结束时,栈不为空,全部出栈
{
changed += ' ';
changed += s.top();
s.pop();
}
return changed;
}
//计算后缀表达式
double result(string str)
{
Stack stack;
int num = 0, flag = 0, fushu = 0;
for (int i = 0; i < str.length(); i++)
{
if (str[i] >= '0' && str[i] <= '9')//遇到数字存入
{
num = num * 10 + str[i] - '0';
flag = 1;//flag用来记录
}
else
{
if (flag)
{
if (fushu)//是否是负数
stack.push(-double(num));
else
stack.push(double(num));
flag = 0;
fushu = 0;
num = 0;
}
if (str[i] == ' ')
{
fushu = 0;
continue;
}
if (str[i] == '-' && str[i + 1] >= '0' && str[i + 1] <= '9')
{
fushu = 1;
continue;
}
double a, b;
a = stack.top();
stack.pop();
b = stack.top();
stack.pop();
stack.push(jisuan(b, a, str[i]));//计算后入栈
}
}
return stack.top();
}
int main()
{
string a, b;
cout << "输入一个中缀表达式(可包含0~9+-*/()):";
cin >> a;
b = change(a);
cout << "转化的后缀表达式为:" << b << endl;
cout << "表达式计算的结果为:" << result(b);
return 0;
}
感谢大家的观看