C++ 数据结构算法 学习笔记(19) - 栈的企业级应用案例(3)
表达式求值程序
给定一个只包含加减乘除法运算的算术表达式,请你编程计算表达式的值
输入格式
输入一行,为需要你计算的表达式,表达式中只包含数字、加法运算符“+”、 减法运算符 “-”、乘法运算符“*”和 除 法运算符“/”,且没有括号,不考虑数值的范围(溢出),待求解的表达式以“=”号结束
例子:12+36/3+45=
完整实现代码:
expression.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#define MAXSIZE 5
#define MaxSize 5
using namespace std;
typedef int ElemType;
typedef struct _SqStack {
ElemType* base;
ElemType* top;
}SqStack;
bool InitStack(SqStack& S)
{
S.base = new ElemType[MaxSize];
if (!S.base)
return false;
S.top = S.base;
return true;
}
bool PushStack(SqStack& S, ElemType e)
{
if (S.top - S.base == MaxSize)
return false;
*(S.top++) = e;
return true;
}
bool PopStack(SqStack & S, ElemType & e)
{
if (S.base == S.top) {
return false;
}
e = *(--S.top);
return true;
}
ElemType* GetTop(SqStack& S)
{
if (S.top != S.base) {
return S.top - 1;
}
else {
return NULL;
}
}
int GetSize(SqStack& S) {
return (S.top - S.base);
}
bool IsEmpty(SqStack& S) {
if (S.top == S.base) {
return true;
}
else {
return false;
}
}
void DestoryStack(SqStack& S) {
if (S.base) {
free(S.base);
S.base = NULL;
S.top = NULL;
}
}
void PrintStack(SqStack& S)
{
if (IsEmpty(S)) return;
ElemType* tmp;
tmp = S.top;
tmp--;
while (tmp != (S.base -1))
{
cout << *tmp << endl;
tmp--;
}
}
expression.cpp
#include <iostream>
#include <string>
#include "expression.h"
using namespace std;
bool is_Larger(const int& lhs, const int& rhs)
{
if ((rhs == '*' || rhs == '/') && (lhs == '*' || lhs == '/')) return true;
if ((rhs == '-' || rhs == '+') && (lhs == '-' || lhs == '+')) return true;
if ((rhs == '+' || rhs == '-') && (lhs == '*' || lhs == '/')) {
return true;
}
return false;
}
int operate(int left, int right, int operate)
{
int result = 0;
cout << "left:" << left << " right:" << right << (char)operate << endl;
switch (operate)
{
case '+':
result = left + right;
break;
case '-':
result = left - right;
break;
case '*':
result = left * right;
break;
case '/':
result = left / right;
break;
default:
break;
}
cout << "result: " << result << endl;
return result;
}
int calculator(string sentence)
{
int ldata= 0, rdata=0;
int status=0;
char opera = '\0';
SqStack data_stack;
SqStack opt_stack;
InitStack(data_stack);
InitStack(opt_stack);
for (int i = 0; i < sentence.length(); i++)
{
if (isspace(sentence[i])) continue;
switch (status)
{
case 0:
if (isdigit(sentence[i]))
{
ldata *= 10;
ldata += sentence[i] - '0';
}
else
{
cout << "It should be a operator symbol!" << endl;
PushStack(data_stack, ldata);
cout << "Already push the previous value " << ldata << " Into the stack" << endl;
ldata = 0;
i--;
status = 1;
}
break;
case 1:
if(sentence[i] == '+' || sentence[i] == '-' || sentence[i] == '*' || sentence[i] == '/')
{
if (IsEmpty(opt_stack))
{
cout << "Is current operator stack is EMPTY, can directly push any operator inside the stack" << endl;
PushStack(opt_stack, sentence[i]);
cout << "The pushed operator is" << (char)(sentence[i]) << endl;
status = 2;
rdata = 0;
}
else
{
if (is_Larger(sentence[i], *GetTop(opt_stack)))
{
cout << "Since the latest operator symbol is larger than the previous in stack operator symbol, therefore can directly insert into the stack" << endl;
PushStack(opt_stack, sentence[i]);
cout << "The latest operator symbol" << sentence[i] << "is being push into the stack" << endl;
status = 2;
rdata = 0;
}
else
{
int left = 0;
int right = 0;
int opera1 = 0;
int new_value = 0;
do
{
PopStack(data_stack, right);
PopStack(data_stack, left);
PopStack(opt_stack, opera1);
new_value = operate(left, right, opera1);
PushStack(data_stack, new_value);
} while (!IsEmpty(opt_stack) && !is_Larger(sentence[i], *GetTop(opt_stack)));
PushStack(opt_stack, sentence[i]);
cout << "The operator of" << sentence[i] << " is sucessfully pushed into the stack";
status = 2;
rdata = 0;
}
}
}
else if (sentence[i] == '=')
{
int left = 0; int right = 0;
int operate1 = 0;
int result = 0;
while (!IsEmpty(opt_stack))
{
PopStack(data_stack, right);
PopStack(data_stack, left);
PopStack(opt_stack, operate1);
result = operate(left, right, operate1);
PushStack(data_stack, result);
}
cout << "The printing data stack is" << endl;
PrintStack(data_stack);
return result;
}
else
{
cout << "The operator symbol is invalid" << endl;
return -1;
}
break;
case 2:
if (isdigit(sentence[i]))
{
rdata *= 10;
rdata += sentence[i] - '0';
}
else
{
cout << "It should be a operator symbol!";
PushStack(data_stack, rdata);
cout << "Already push the previous value " << rdata << " Into the stack" << endl;
i--;
status = 1;
}
break;
}
}
}
int main()
{
string str = "3+4-2*6/3=";
cout << calculator(str) << endl;
system("pause");
return 0;
}