数据结构实验2:栈和队列的实现和应用

实验内容

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

感谢大家的观看

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值