表达式求值

 /*
用到了atof()字符转浮点,以及C++中方法的重载
只含加减乘除的简单算术表达式
1.先乘除后加减
2.从左算到右
3.先括号内后括号外
4.暂定输入的表达式不会出现语法错误
算法有点前序遍历既视感
*/
#ifndef PCH_H
#define PCH_H
#include<stdio.h>
#include <stdlib.h>
#include<cstdlib>
#include<iostream>
#include<math.h>
#include<malloc.h>
constexpr auto ERROR = 0;
constexpr auto OK = 1;
typedef int Status;
// TODO: 添加要在此处预编译的标头
typedef struct StackNode
{//运算符栈
    char ch;
    struct StackNode *next;
}StackNode,*LinkStack;
typedef struct StackNum
{//数字栈
    double ch;
    struct StackNum *next;
}StackNum, *LinkNum;
Status InitStack(LinkStack &S);//初始化符号栈√
Status InitStack(LinkNum &N); //初始化数字栈√
Status Push(LinkStack &S,char ch);//入栈√
Status Push(LinkNum &S, double ch);//入栈√
Status Pop(LinkStack &S,char &e);//出栈√
Status Pop(LinkNum &N, double &e);
char Gettop(LinkStack S);//获取栈顶元素√
double Gettop(LinkNum N);
Status In(char ch);//判断是否为运算符,是返回1,不是返回0√
char Precede(char a,char b);//比较两个字符之间的优先级√
double Operate(double a,char theta,double b);//运算√
double EvaluateExpression();//计算表达式√返回数字栈顶
#endif //PCH_H
--------------------------------------------------------------------------
// pch.cpp: 与预编译标头对应的源文件;编译成功所必需的

#include "pch.h"

// 一般情况下,忽略此文件,但如果你使用的是预编译标头,请保留它。

Status InitStack(LinkStack &S)
{
    S = NULL;//初始S为栈底,链尾
    return OK;
}

Status InitStack(LinkNum & N)
{//方法重载
    N = NULL;
    return OK;
}
Status Push(LinkStack & S, char ch)
{
    StackNode *p = (LinkStack )malloc(sizeof(StackNode));
    p->ch = ch;
    p->next = S;
    S = p;//更新S为栈顶
    return OK;
}
Status Push(LinkNum & N, double ch)
{
    StackNum *p = (LinkNum )malloc(sizeof(StackNum));
    p->ch = ch;
    p->next = N;
    N = p;//更新N为栈顶
    return OK;
}
Status Pop(LinkStack & S, char & e)
{
    if (S != NULL) e = S->ch;
    StackNode *p = S;
    S = S->next;
    delete p;
    return OK;
}

Status Pop(LinkNum & N, double &e)
{
    if (N != NULL) e = N->ch;
    StackNum *p = N;
    N = N->next;
    delete p;
    return OK;
}
char Gettop(LinkStack S)
{
    if (S != NULL) return S->ch;
    return 0;
}
double Gettop(LinkNum N)
{
    if (N != NULL) return N->ch;
    return 0;
}
Status In(char ch)
{
    switch (ch)
    {
    case '+':
    case '-':
    case '*':
    case '/':
    case '#':
    case '(':
    case ')':
        return OK;
        break;
    default:
        return ERROR;
        break;
    }
}
char Precede(char a, char b)
{
    if (a=='+'||a=='-')
    {
        switch (b)
        {
        case '+':return '>'; break;
        case '-':return '>'; break;
        case '*':return '<'; break;
        case '/':return '<'; break;
        case '(':return '<'; break;
        case ')':return '>'; break;
        case '#':return '>'; break;
        default:
            break;
        }
    }
    else if (a=='*'||a=='/')
    {
        switch (b)
        {
        case '+':return '>'; break;
        case '-':return '>'; break;
        case '*':return '>'; break;
        case '/':return '>'; break;
        case '(':return '<'; break;
        case ')':return '>'; break;
        case '#':return '>'; break;
        default:
            break;
        }
    }
    else if(a=='(')
    {
        switch (b)
        {
        case '+':return '<'; break;
        case '-':return '<'; break;
        case '*':return '<'; break;
        case '/':return '<'; break;
        case '(':return '<'; break;
        case ')':return '='; break;
        default:
            break;
        }
    }else if(a==')')
    {
        switch (b)
        {
        case '+':return '>'; break;
        case '-':return '>'; break;
        case '*':return '>'; break;
        case '/':return '>'; break;
        case ')':return '>'; break;
        case '#':return '>'; break;
        default:
            break;
        }
    }
    else if (a=='#')
    {
        switch (b)
        {
        case '+':return '<'; break;
        case '-':return '<'; break;
        case '*':return '<'; break;
        case '/':return '<'; break;
        case '(':return '<'; break;
        case '#':return '='; break;
        default:
            break;
        }
    }
    return 0;
}
double Operate(double a, char theta, double b)
{
    double result = 0;
    switch (theta)
    {
    case '+':
        result = a + b;
        break;
    case '-':
        result= a - b;
        break;
    case '*':
        result = a * b;
        break;
    case '/':
        result = a / b;
        break;
    default:std::cout <<"非法运算符";
        break;
    }
    return result;
}
double EvaluateExpression()
{
    char ch;//记录输入的字符
    char theta;//记录弹出的运算符
    char x;//弹出的括号(
    double a;//弹出的前一个录入的运算数
    double b;//弹出后一个录入的运算数
    LinkStack OPTR;
    LinkNum OPND;
    InitStack(OPND);//数字栈
    InitStack(OPTR);//运算符栈
    Push(OPTR,'#');//起始结尾标志均为#
    std::cin >> ch;//录入第一个字符
    while (ch!='#'||Gettop(OPTR)!='#')//表达式未扫描完毕||已扫描完表达式未计算完毕
    {
        if (!In(ch))
        {
            char *p = (char *)malloc(sizeof(char));
            *p = ch;//将其转化为浮点数
            Push(OPND, atof(p)); std::cin >> ch;
        }
        else
        {
            switch (Precede(Gettop(OPTR),ch))
            {
            case '>':
                Pop(OPTR, theta);
                Pop(OPND, b);
                Pop(OPND, a);
                Push(OPND,Operate(a,theta,b));
                break;
            case'<':
                Push(OPTR, ch);
                std::cin >> ch;
                break;
            case '=':
                Pop(OPTR, x);
                std::cin >> ch;
                break;
            default:
                break;
            }
        }

    }
    return Gettop(OPND);
}
// EvaluateExpression.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>

int main()
{
    std::cout<<EvaluateExpression();
    system("pause");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值