/*
用到了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");
}
表达式求值
最新推荐文章于 2024-01-28 21:10:31 发布