c语言链栈带括号的四则运算,链式栈实现四则运算,表达式可包含括号,可计算小数...

由于代码中的注释已较为详尽,在此就只贴代码了

ExprCPro.cpp

#include "pch.h"

#include"Expr.h"

#include

using namespace std;

int main()

{

cout << "-------------表达式求值--------------" << endl;

cout << "1.支持四则运算符:+ - * /" << endl;

cout << "2.支持括号()"<< endl;

cout << "3.支持浮点数" << endl;

cout << "例如:5*(3+4)/2" << endl;

cout << "请输入您要计算的表达式" << endl;

char expr[100] = { 0 };

cin >> expr;

cout << "最后的计算结果为:" << endl;

cout << parse(expr);

return 0;

}

Expr.h(头文件)

#include

using namespace std;

//操作数栈

typedef struct StackNodeOPND

{

double value;

StackNodeOPND * next;

}*OPND;

//操作符栈

typedef struct StackNodeOPTR

{

char op;

StackNodeOPTR * next;

}*OPTR;

int init(OPND& opnd);//初始化操作数栈函数

int init(OPTR& optr);//初始化操作符栈函数

int push(OPND& opnd, double value);//入操作数栈

int push(OPTR&optr, char c);//入操作符栈

double parse(const char expr[]);//解析表达式,将操作数和操作符分别压入操作数栈和操作符栈

int getTop(OPTR&optr, char&c);//获得操作符栈的栈顶操作符

char preorder(char a, char b);//比较当前运算符和栈顶运算符的优先级

int pop(OPTR&optr, char &c);//运算符栈顶元素出栈,并获取栈顶元素

int pop(OPND&opnd, double &value);//操作数栈顶元素出栈,并获取栈顶元素

double cal(double a, double b, char op);//计算函数

bool isEmpty(OPTR&optr);//判断运算符栈中是否还有运算符

Expr.cpp

#include"Expr.h"

int init(OPND& opnd)

{

//保证链表为空,消除链表中的元素

while (opnd != NULL) {

OPND temp = opnd;

opnd = temp->next;

delete(temp);

}

opnd = NULL;

return 0;

}

int init(OPTR& optr) {

//保证链表为空,消除链表中的元素

while (optr != NULL) {

OPTR temp = optr;

optr= temp->next;

delete(temp);

}

optr= NULL;

return 0;

}

//入操作数栈函数

int push(OPND& opnd, double value) {

OPND temp = (OPND)malloc(sizeof(StackNodeOPND));

if (!temp) {

return -1;

}

temp->value = value;

temp->next = opnd;

opnd = temp;

return 0;

}

//入操作符栈函数

int push(OPTR& optr, char c) {

OPTR temp = (OPTR)malloc(sizeof( StackNodeOPTR));

if (!temp) {

return -1;

}

temp->op = c;

temp->next = optr;

optr= temp;

return 0;

}

//弹出操作符栈顶元素,并同时获取栈顶元素

int pop(OPTR&optr, char& c) {

if (optr == NULL) {

return -1;

}

OPTR temp = optr;

c = optr->op;

optr = optr->next;

delete(temp);

return 0;

}

int pop(OPND&opnd, double &value) {

if (opnd == NULL) {

return -1;

}

OPND temp = opnd;

value = temp->value;

opnd = opnd->next;

delete(temp);

return 0;

}

//解析表达式

double parse(const char expr[])

{

OPND opnd = NULL;//操作数栈

OPTR optr = NULL;//操作符栈

init(opnd);

init(optr);

for (int i = 0; expr[i] != '\0'; i++) {

//读一个字符

char c = expr[i];

if ((c >= '0'&&c <= '9') || c == '.') {

char token[50] = { 0 };

int j = 0;

while ((expr[i + j] > '0'&&expr[i + j] < '9') || expr[i + j] == '.') {

token[j] = expr[i + j];

j++;

}

i = i + j - 1;

token[j] = '\0';

double value = atof(token);

push(opnd, value);

}

else {

char op = 0;

getTop(optr, op);

if (op != 0) {

switch (preorder(op, c))

{

case'

push(optr, c);

break;

case'='://括号相遇,弹出括号

pop(optr, op);

break;

case'>'://取操作符栈顶元素并取操作数栈顶两个运算

double a = 0;

double b = 0;

pop(opnd, a);

pop(opnd, b);

pop(optr, op);

push(opnd, cal(a, b, op));

i--;//仍要比较当前操作符和下一个栈顶操作符

break;

}

}

else {

push(optr, c);

}

}

}

if (!isEmpty(optr)) {

double a = 0;

double b = 0;

char op = 0;

pop(opnd, a);

pop(opnd, b);

pop(optr, op);

push(opnd, cal(a, b, op));

}

double result = 0;

pop(opnd, result);

return result;

}

int getTop(OPTR&optr, char&c) {

if (optr == NULL) {

return -1;

}

c = optr->op;

return 0;

}

//a是栈顶操作符,b是当前操作符

char preorder(char a, char b) {

//用一个二维数组来保存两两运算符之间的优先级关系

//返回类型有三种">,

char compre[6][6]{

//当前左括号和栈顶右括号比其他运算符优先级都高,两者相等

//当前右括号和栈顶左括号比其他运算符优先级都低,两者相等

//+ - * / ( )

{'>','>','>','>',''},//+

{'>','>','>','>',''},//-

{'','>',''},//*

{'','>',''},// /

{'

{'>','>','>','>','=','>'}// )

};

int x=-1, y = -1;

char allch[7] = "+-*/()";

for (int i = 0; i < 6; i++) {

if (a == allch[i]) {

x = i;

}

if (b == allch[i]) {

y = i;

}

}

return compre[x][y];

}

double cal(double a, double b, char op) {

double result;

switch (op) {

case'*':

result = b * a;

break;

case'/':

result = b / a;

break;

case'+':

result = b + a;

break;

case'-':

result = b - a;

break;

default:

{

cout << "您输入的表达式符号有误,请重新输入!";

exit(0);

}

}

return result;

}

bool isEmpty(OPTR&optr) {

if (optr == NULL) {

return 1;

}

else

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值