哈工大数据结构作业2-线性结构及其应用

  本文是笔者2020年秋哈工大数据结构作业2自己的代码,由于本人能力有限,可能存在一些错误,欢迎指出。

本文仅供参考,严禁抄袭!

  2020年秋的作业2是二选一,笔者选的是算术表达式求值。由于撰写该篇博文时距编写该作业源代码已有半年多的时间,因此再看这些代码,发现写的又臭又长,思路早已不清晰。这里只将代码放上,恕难详细描述思路,希望有心的读者耐心阅读源码,若有不通之处可评论或私聊。

源代码完整版资源链接:https://download.csdn.net/download/qq_45853731/20213114?spm=1001.2014.3001.5503

作业题目:算术表达式求值

  表达式求值是实现程序设计语言的基本问题之一,也是栈的应用的一个典型例子。一个算术表达式是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。假设操作数是正整数,运算符只含加减乘除等四种二元运算符,界限符有左右括号和表达式起始、结束符“#”,如:#(7+15)*(23-28/4)#。引入表达式起始、结束符是为了方便。设计一个程序,演示用算符优先法对算术表达式求值的过程。

基本数据结构

#define Maxlength 100
#define Charlen 100

typedef char Elementtype;
struct STACK {
    int top;
    Elementtype elements[Maxlength];
};
struct STACKNUM {
    int top;
    double elements[Maxlength];
};
char sufExpression[Charlen];

辅助函数

//将栈置空
void MakeNull(STACK& S)
{
    S.top = Maxlength;
}
//判断栈是否为空
bool Empty(STACK S)
{
    if (S.top > Maxlength - 1)
        return true;
    else
        return false;
}
//判断栈是否为空
bool EmptyNum(STACKNUM Sres)
{
    if (Sres.top > Maxlength - 1)
        return true;
    else
        return false;
}
//返回栈顶元素
Elementtype Top(STACK S)
{
    if (Empty(S))
    {
        return '0';
    }
    else
    {
        return S.elements[S.top];
    }
}
//打印栈信息
void PrintStack(STACK S)
{
    cout << "现在栈中,从栈顶到栈底依次为:";
    for (int i = S.top; i < Maxlength; i++)
    {
        cout << S.elements[i] << ' ';
    }
    cout << endl;
}
//打印栈信息
void PrintNumStack(STACKNUM Sres)
{
    cout << "现在栈中,从栈顶到栈底依次为:";
    for (int i = Sres.top; i < Maxlength; i++)
    {
        cout << Sres.elements[i] << ' ';
    }
    cout << endl;
}
//将栈顶元素弹出
void Pop(STACK& S)
{
    if (Empty(S))
        cout << "stack is empty" << endl;
    else
    {
        cout << "令" << S.elements[S.top] << "出栈,";
        S.top = S.top + 1;
        PrintStack(S);
    }
}
//将栈顶元素弹出
void PopNum(STACKNUM& Sres)
{
    if (EmptyNum(Sres))
        cout << "stack is empty" << endl;
    else
    {
        cout << "令" << Sres.elements[Sres.top] << "出栈,";
        Sres.top = Sres.top + 1;
        PrintNumStack(Sres);
    }
}
//压栈
void Push(Elementtype x, STACK& S)
{
    if (S.top == 0)
        cout << "stack is full" << endl;
    else
    {
        cout << "将" << x << "入栈,";
        S.top -= 1;
        S.elements[S.top] = x;
        PrintStack(S);
    }
}
//压栈
void PushNum(double x, STACKNUM& Sres)
{
    if (Sres.top == 0)
        cout << "stack is full" << endl;
    else
    {
        cout << "将" << x << "入栈,";
        Sres.top -= 1;
        Sres.elements[Sres.top] = x;
        PrintNumStack(Sres);
    }
}

从文本文件输入任意一个语法正确的(中缀)表达式,显示并保存该表达式

ifstream in("result.txt");
    in >> c;
    in >> c;
    while (c != '#')
    {
        cout << c;
        in >> c;
    }
    in.close();

文本中保存的表达式格式如下:

#(12.1*2.2^2+3.4)*(4-12/6)#

注:这里只是将文件中的表达式读取到了控制台上,并未保存,真正的保存操作在下一节void Trans函数中。
 

利用栈结构,把上述(中缀)表达式转换成后缀表达式,并显示栈的状态变化过程和所得到的后缀表达式

void Trans(STACK& S)//中缀转后缀
{
    char c, prec;
    int i = 0;
    ifstream in("result.txt");
    in >> c;
    in >> c;
    prec = c;
    while (c != '#')
    {
        if (c == '(')
        {
            Push(c, S);
        }
        else if (c == ')')
        {
            while (Empty(S) == false)
            {
                if (S.elements[S.top] != '(')
                {
                    sufExpression[i] = S.elements[S.top];
                    i++;
                    sufExpression[i] = ' ';
                    i++;
                }
                if (S.elements[S.top] == '(')
                {
                    Pop(S);
                    break;
                }
                Pop(S);
            }
        }
        else if (c == '*')
        {
            while (S.elements[S.top] == '^'||S.elements[S.top] == '/')
            {
                sufExpression[i] = S.elements[S.top];
                i++;
                sufExpression[i] = ' ';
                i++;
                Pop(S);
            }
            Push(c, S);
        }
        else if (c == '/')
        {
            while (S.elements[S.top] == '^' || S.elements[S.top] == '*')
            {
                sufExpression[i] = S.elements[S.top];
                i++;
                sufExpression[i] = ' ';
                i++;
                Pop(S);
            }
            Push(c, S);
        }
        else if (c == '^')
        {
            Push(c, S);
        }
        else if (c == '+')
        {
            while (S.elements[S.top] == '*' || S.elements[S.top] == '/' || S.elements[S.top] == '^'||S.elements[S.top]=='-')
            {
                sufExpression[i] = S.elements[S.top];
                i++;
                sufExpression[i] = ' ';
                i++;
                Pop(S);
            }
            Push(c, S);
        }
        else if (c == '-')
        {
            while (S.elements[S.top] == '*' || S.elements[S.top] == '/' || S.elements[S.top] == '^' || S.elements[S.top] == '+')
            {
                sufExpression[i] = S.elements[S.top];
                i++;
                sufExpression[i] = ' ';
                i++;
                Pop(S);
            }
            Push(c, S);
        }
        else if (c <= '9' && c >= '0' || c == '.')
        {
            sufExpression[i] = c;
            i++;
        }
        prec = c;
        in >> c;
        if ((prec <= '9' && prec >= '0') && (c == '+' || c == '-' || c == '*' || c == '/' || c == ')' || c == '^'))
        {
            sufExpression[i] = ' ';
            i++;
        }
    }
    while (Empty(S) == false)
    {
        if (S.elements[S.top] != '(')
        {
            sufExpression[i] = ' ';
            i++;
            sufExpression[i] = S.elements[S.top];
            i++;
            sufExpression[i] = ' ';
            i++;
        }
        Pop(S);
    }
    sufExpression[i] = '\0';
    in.close();
}

 

利用栈结构,对后缀表达式进行求值,并显示栈的状态变化过程和最终结果

void Calcu(STACKNUM& Sres)//计算结果
{
    double result;
    int i = 0, weight = 0, decimal = 0, flag = 0;
    while (sufExpression[i] != '\0')
    {
        if (sufExpression[i] >= '0' && sufExpression[i] <= '9')
        {
            int j = i;
            while (sufExpression[j] != ' ')
            {
                if (sufExpression[j] == '.')
                {
                    flag = 1;
                    break;
                }
                weight++;
                j++;
            }
            if (flag == 1)
            {
                j++;
                while (sufExpression[j] != ' ')
                {
                    decimal++;
                    j++;
                }
            }
            flag = 0;
            result = 0;
            while (sufExpression[i] != ' ')
            {
                if (sufExpression[i] == '.')
                {
                    flag = 1;
                    break;
                }
                result += pow(10, weight - 1) * int(sufExpression[i] - '0');
                weight--;
                i++;
            }
            if (flag == 1)
            {
                i++;
                for (int k = 1; k <= decimal; k++)
                {
                    result += pow(10, -decimal) * int(sufExpression[i] - '0');
                    i++;
                }
            }
            decimal = 0;
            PushNum(result, Sres);
        }
        else if (sufExpression[i] == '+')
        {
            result = Sres.elements[Sres.top] + Sres.elements[Sres.top + 1];
            PopNum(Sres);
            PopNum(Sres);
            PushNum(result, Sres);
        }
        else if (sufExpression[i] == '-')
        {
            result = Sres.elements[Sres.top + 1] - Sres.elements[Sres.top];
            PopNum(Sres);
            PopNum(Sres);
            PushNum(result, Sres);
        }
        else if (sufExpression[i] == '*')
        {
            result = Sres.elements[Sres.top + 1] * Sres.elements[Sres.top];
            PopNum(Sres);
            PopNum(Sres);
            PushNum(result, Sres);
        }
        else if (sufExpression[i] == '/')
        {
            if (Sres.elements[Sres.top] == 0)
            {
                cout << "除数不能为0" << endl;
            }
            else
            {
                result = Sres.elements[Sres.top + 1] / Sres.elements[Sres.top];
                PopNum(Sres);
                PopNum(Sres);
                PushNum(result, Sres);
            }
        }
        else if (sufExpression[i] == '^')
        {
            result = pow(Sres.elements[Sres.top + 1], Sres.elements[Sres.top]);
            PopNum(Sres);
            PopNum(Sres);
            PushNum(result, Sres);
        }
        i++;
    }
    cout << endl << "计算结果为:";
    cout << Sres.elements[Sres.top] << endl << endl;
    cout << "下面是结合2、3的算符优先法的过程:" << endl << endl;
}

 

将操作数类型扩充到实数、扩充运算符集合,并引入变量操作数,来完成表达式求值

该要求已经在前两节中扩充。
 

设计和实现结合 3 和 4 的算符优先法

void Merge(STACK& S, STACKNUM& Sres)//结合2、3的算符优先法
{
    char c, prec;
    int i = 0, j = 0;
    int weight = 0;
    double decimal = 1, result = 0;
    ifstream in("result.txt");
    in >> c;
    in >> c;
    prec = c;
    while (c != '#')
    {
        prec = c;
        if (c == '(')
        {
            Push(c, S);
            in >> c;
        }
        else if (c == ')')
        {
            while (Empty(S) == false)
            {
                if (S.elements[S.top] != '(')
                {
                    sufExpression[i] = S.elements[S.top];
                    i++;
                    sufExpression[i] = ' ';
                    i++;
                }
                if (S.elements[S.top] == '+')
                {
                    result = Sres.elements[Sres.top] + Sres.elements[Sres.top + 1];
                    PopNum(Sres);
                    PopNum(Sres);
                    PushNum(result, Sres);
                    result = 0;
                }
                else if (S.elements[S.top] == '-')
                {
                    result = Sres.elements[Sres.top + 1] - Sres.elements[Sres.top];
                    PopNum(Sres);
                    PopNum(Sres);
                    PushNum(result, Sres);
                    result = 0;
                }
                else if (S.elements[S.top] == '*')
                {
                    result = Sres.elements[Sres.top + 1] * Sres.elements[Sres.top];
                    PopNum(Sres);
                    PopNum(Sres);
                    PushNum(result, Sres);
                    result = 0;
                }
                else if (S.elements[S.top] == '/')
                {
                    if (Sres.elements[Sres.top] == 0)
                    {
                        cout << "除数不能为0" << endl;
                    }
                    else
                    {
                        result = Sres.elements[Sres.top + 1] / Sres.elements[Sres.top];
                        PopNum(Sres);
                        PopNum(Sres);
                        PushNum(result, Sres);
                        result = 0;
                    }
                }
                else if (S.elements[S.top] == '^')
                {
                    result = pow(Sres.elements[Sres.top + 1], Sres.elements[Sres.top]);
                    PopNum(Sres);
                    PopNum(Sres);
                    PushNum(result, Sres);
                    result = 0;
                }
                if (S.elements[S.top] == '(')
                {
                    Pop(S);
                    break;
                }
                Pop(S);
            }
            in >> c;
        }
        else if (c == '*')
        {
            while (S.elements[S.top] == '^'|| S.elements[S.top] == '/')
            {
                sufExpression[i] = S.elements[S.top];
                i++;
                sufExpression[i] = ' ';
                i++;
                if (S.elements[S.top] == '^')
                {
                    result = pow(Sres.elements[Sres.top + 1], Sres.elements[Sres.top]);
                    PopNum(Sres);
                    PopNum(Sres);
                    PushNum(result, Sres);
                    result = 0;
                }
                else if (S.elements[S.top] == '/')
                {
                    if (Sres.elements[Sres.top] == 0)
                    {
                        cout << "除数不能为0" << endl;
                    }
                    else
                    {
                        result = Sres.elements[Sres.top + 1] / Sres.elements[Sres.top];
                        PopNum(Sres);
                        PopNum(Sres);
                        PushNum(result, Sres);
                        result = 0;
                    }
                }
                Pop(S);
            }
            Push(c, S);
            in >> c;
        }
        else if (c == '/')
        {
            while (S.elements[S.top] == '^' || S.elements[S.top] == '*')
            {
                sufExpression[i] = S.elements[S.top];
                i++;
                sufExpression[i] = ' ';
                i++;
                if (S.elements[S.top] == '^')
                {
                    result = pow(Sres.elements[Sres.top + 1], Sres.elements[Sres.top]);
                    PopNum(Sres);
                    PopNum(Sres);
                    PushNum(result, Sres);
                    result = 0;
                }
                else if (S.elements[S.top] == '*')
                {
                    result = Sres.elements[Sres.top + 1] * Sres.elements[Sres.top];
                    PopNum(Sres);
                    PopNum(Sres);
                    PushNum(result, Sres);
                    result = 0;
                }
                Pop(S);
            }
            Push(c, S);
            in >> c;
        }
        else if (c == '^')
        {
            Push(c, S);
            in >> c;
        }
        else if (c == '+')
        {
            while (S.elements[S.top] == '*' || S.elements[S.top] == '/' || S.elements[S.top] == '^'|| S.elements[S.top] == '-')
            {
                sufExpression[i] = S.elements[S.top];
                i++;
                sufExpression[i] = ' ';
                i++;
                if (S.elements[S.top] == '*')
                {
                    result = Sres.elements[Sres.top + 1] * Sres.elements[Sres.top];
                    PopNum(Sres);
                    PopNum(Sres);
                    PushNum(result, Sres);
                    result = 0;
                }
                else if (S.elements[S.top] == '/')
                {
                    if (Sres.elements[Sres.top] == 0)
                    {
                        cout << "除数不能为0" << endl;
                    }
                    else
                    {
                        result = Sres.elements[Sres.top + 1] / Sres.elements[Sres.top];
                        PopNum(Sres);
                        PopNum(Sres);
                        PushNum(result, Sres);
                        result = 0;
                    }
                }
                else if (S.elements[S.top] == '^')
                {
                    result = pow(Sres.elements[Sres.top + 1], Sres.elements[Sres.top]);
                    PopNum(Sres);
                    PopNum(Sres);
                    PushNum(result, Sres);
                    result = 0;
                }
                else if (S.elements[S.top] == '-')
                {
                    result = Sres.elements[Sres.top + 1] - Sres.elements[Sres.top];
                    PopNum(Sres);
                    PopNum(Sres);
                    PushNum(result, Sres);
                    result = 0;
                }
                Pop(S);
            }
            Push(c, S);
            in >> c;
        }
        else if (c == '-')
        {
        while (S.elements[S.top] == '*' || S.elements[S.top] == '/' || S.elements[S.top] == '^' || S.elements[S.top] == '+')
        {
            sufExpression[i] = S.elements[S.top];
            i++;
            sufExpression[i] = ' ';
            i++;
            if (S.elements[S.top] == '*')
            {
                result = Sres.elements[Sres.top + 1] * Sres.elements[Sres.top];
                PopNum(Sres);
                PopNum(Sres);
                PushNum(result, Sres);
                result = 0;
            }
            else if (S.elements[S.top] == '/')
            {
                if (Sres.elements[Sres.top] == 0)
                {
                    cout << "除数不能为0" << endl;
                }
                else
                {
                    result = Sres.elements[Sres.top + 1] / Sres.elements[Sres.top];
                    PopNum(Sres);
                    PopNum(Sres);
                    PushNum(result, Sres);
                    result = 0;
                }
            }
            else if (S.elements[S.top] == '^')
            {
                result = pow(Sres.elements[Sres.top + 1], Sres.elements[Sres.top]);
                PopNum(Sres);
                PopNum(Sres);
                PushNum(result, Sres);
                result = 0;
            }
            else if (S.elements[S.top] == '+')
            {
                result = Sres.elements[Sres.top + 1] + Sres.elements[Sres.top];
                PopNum(Sres);
                PopNum(Sres);
                PushNum(result, Sres);
                result = 0;
            }
            Pop(S);
        }
        Push(c, S);
        in >> c;
        }
        else if (c <= '9' && c >= '0' || c == '.')
        {
            if(c >= '0' && c <= '9')
            {
                j = i;
                while (c >= '0' && c <= '9')
                {
                    weight++;
                    sufExpression[i] = c;
                    i++;
                    in >> c;
                }
                while (weight > 0)
                {
                    result += pow(10, weight - 1) * int(sufExpression[j] - '0');
                    j++;
                    weight--;
                }
            }
            if(c=='.')
            {
                sufExpression[i] = c;
                i++;
                in >> c;
                while (c <= '9' && c >= '0')
                {
                    sufExpression[i] = c;
                    i++;
                    decimal = decimal * 0.1;
                    result += decimal * int(c - '0');
                    in >> c;
                }
                decimal = 1;
            }
            PushNum(result, Sres);
            result = 0;
        }
        if ((prec <= '9' && prec >= '0') && (c == '+' || c == '-' || c == '*' || c == '/' || c == ')' || c == '^'))
        {
            sufExpression[i] = ' ';
            i++;
        }
    }
    while (Empty(S) == false)
    {
        if (S.elements[S.top] != '(')
        {
            sufExpression[i] = S.elements[S.top];
            i++;
            sufExpression[i] = ' ';
            i++;
        }
        if (S.elements[S.top] == '+')
        {
            result = Sres.elements[Sres.top] + Sres.elements[Sres.top + 1];
            PopNum(Sres);
            PopNum(Sres);
            PushNum(result, Sres);
            result = 0;
        }
        else if (S.elements[S.top] == '-')
        {
            result = Sres.elements[Sres.top + 1] - Sres.elements[Sres.top];
            PopNum(Sres);
            PopNum(Sres);
            PushNum(result, Sres);
            result = 0;
        }
        else if (S.elements[S.top] == '*')
        {
            result = Sres.elements[Sres.top + 1] * Sres.elements[Sres.top];
            PopNum(Sres);
            PopNum(Sres);
            PushNum(result, Sres);
            result = 0;
        }
        else if (S.elements[S.top] == '/')
        {
            if (Sres.elements[Sres.top] == 0)
            {
                cout << "除数不能为0" << endl;
            }
            else
            {
                result = Sres.elements[Sres.top + 1] / Sres.elements[Sres.top];
                PopNum(Sres);
                PopNum(Sres);
                PushNum(result, Sres);
                result = 0;
            }
        }
        else if (S.elements[S.top] == '^')
        {
            result = pow(Sres.elements[Sres.top + 1], Sres.elements[Sres.top]);
            PopNum(Sres);
            PopNum(Sres);
            PushNum(result, Sres);
            result = 0;
        }
        Pop(S);
    }
    sufExpression[i] = '\0';
    in.close();
    cout << Sres.elements[Sres.top] << endl;
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值