用栈实现 表达式求值的运算源码

 

说明:表达式以#结尾

 

// Evaluate.cpp : Defines the entry point for the console application.

//

 

#include "stdafx.h"

 

#define STACK_SIZE 100

#define BIG 1

#define SMALL -1

#define EQUAL 0

//#define TRUE 1

//using namespace std;

class Stack

{

public:

Stack();

~Stack();

void iniStack();

void desStack();

void push(int a);

bool isEmpty();

int getTop();

int pop();

//getElem();

private:

int *data;

int top;

int length;

 

};

Stack::Stack()

{

top = -1;

length = 0;

data = NULL;

}

Stack::~Stack()

{

 

}

void Stack::iniStack()

{

data = new int[STACK_SIZE];

}

void Stack::desStack()

{

delete [] data;

data = NULL;

}

void Stack::push(int a)

{

top++;

data[top] = a;

}

int Stack::pop()

{

return data[top--];

}

bool Stack::isEmpty()

{

return top == -1;

}

int Stack::getTop()

{

return data[top];

}

int precede(char a,char b)

{

int r = 0;

switch (a)

{

case '+':

if (b == '+' || b == '-' || b == ')' || b == '#')

r = BIG;

else if(b == '*' || b == '/' || b == '(' )

r = SMALL;

break;

case '-':

if (b == '+' || b == '-' || b == ')' || b == '#')

r = BIG;

else if(b == '*' || b == '/' || b == '(')

r = SMALL;

break;

case '*':

if ( b == '(' )

r = SMALL;

else if(b == '+' || b == '-' || b == '*' || b == '/' || b == ')'|| b == '#')

r = BIG;

break;

case '/':

if ( b == '(' )

r = SMALL;

else if(b == '+' || b == '-' || b == '*' || b == '/' || b == ')'|| b == '#')

r = BIG;

break;

case '(':

if(b == '+' || b == '-' || b == '*' || b == '/' || b == '(')

r = SMALL;

else if(b == ')')

r = EQUAL;

break;

case ')':

r = BIG;

case '#':

if(b == '#')

r = EQUAL;

else

r = SMALL;

break;

}

return r;

}

bool isOpertor(char a)

{

return (a=='+' || a=='-' || a=='*' || a=='/' || a=='(' || a==')' || a=='#');

}

int jisuan(int a,int b,char opertor)

{

switch (opertor)

{

case '+':

return a + b;

break;

case '-':

return a - b;

break;

case '*':

return a * b;

break;

case '/':

return a / b;

break;

}

}

int main(int argc, char* argv[])

{

 

Stack oper,opnd;

oper.iniStack();

oper.push('#');

opnd.iniStack();

char instr[100] = {0};

scanf("%s",instr);

//printf("%s/n" , instr);

int i=0;

int j=0;

char temp;

char t1[100] = {0};

while (instr[i] != NULL)

{

if(!isOpertor(instr[i]))//如果不是操作符号

t1[j++] = instr[i];

//opnd.push(instr[i]-48);

 

else 

{

j=0;

int a = atoi(t1);

memset(t1,0,100);

opnd.push(a);

while (precede(oper.getTop(),instr[i]) == BIG )//如果之前进栈的运算符优先级更高,则先运算之前的

{

opnd.push(jisuan(opnd.pop(),opnd.pop(),oper.pop()));

}

if( precede(oper.getTop(),instr[i]) == SMALL )

{

oper.push(instr[i]);

}

 

else if( precede(oper.getTop(),instr[i]) == EQUAL)

oper.pop();

}

i++;

 

}

printf("%d/n",opnd.pop());

oper.desStack();

opnd.desStack();

return 0;

}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会为您撰写一份包含详细源码表达式求值报告,包括将算术表达式转化为逆波兰式和对逆波兰式求值两个部分。 一、将算术表达式转化为逆波兰式 下面是将算术表达式转化为逆波兰式的源代码: ```python class Solution: def calculate(self, s: str) -> int: stack = [] res = [] priority = {'+': 1, '-': 1, '*': 2, '/': 2, '(': 0} for c in s: if c.isdigit(): res.append(c) elif c == '(': stack.append(c) elif c == ')': while stack and stack[-1] != '(': res.append(stack.pop()) stack.pop() # 弹出左括号 else: while stack and priority[c] <= priority[stack[-1]]: res.append(stack.pop()) stack.append(c) while stack: res.append(stack.pop()) return res ``` 这里使用了两个栈,一个栈用于存储操作数,一个栈用于存储操作符。具体实现如下: 1. 遍历中缀表达式中的每个字符。 2. 如果当前字符是数字,则将其添加到结果列表中。 3. 如果当前字符是左括号,则将其入栈。 4. 如果当前字符是右括号,则弹出栈中的所有操作符直到遇到左括号,并将这些操作符添加到结果列表中。 5. 如果当前字符是操作符,则比较其与栈顶操作符的优先级,如果当前操作符的优先级小于等于栈顶操作符的优先级,则弹出栈顶操作符并添加到结果列表中,重复此过程直到栈顶操作符的优先级小于当前操作符的优先级,然后将当前操作符入栈。 6. 遍历完中缀表达式后,将栈中剩余的操作符全部弹出并添加到结果列表中。 7. 返回结果列表。 这样就得到了中缀表达式对应的逆波兰式。例如,将中缀表达式"3+4*2/(1-5)^2"转换为逆波兰式的结果为"3 4 2 * 1 5 - 2 ^ / +"。 二、对逆波兰式求值 下面是对逆波兰式求值的源代码: ```python class Solution: def evalRPN(self, tokens: List[str]) -> int: stack = [] for token in tokens: if token in '+-*/': num2 = stack.pop() num1 = stack.pop() if token == '+': stack.append(num1 + num2) elif token == '-': stack.append(num1 - num2) elif token == '*': stack.append(num1 * num2) else: stack.append(int(num1 / num2)) else: stack.append(int(token)) return stack[-1] ``` 这里使用了一个栈,遍历逆波兰式中的每个元素,如果当前元素是数字,则将其入栈,如果当前元素是操作符,则从栈顶弹出两个元素进行相应的运算,并将运算结果入栈。最后栈中剩余的元素就是表达式的求值结果。 例如,对逆波兰式"3 4 2 * 1 5 - 2 ^ / +"求值的结果为3.1875。 综上所述,通过将中缀表达式转换为逆波兰式并对其求值,我们可以得到数学表达式的精确计算结果,同时避免了括号对运算顺序的影响,提高了计算的效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值