1018: 表达式求值
Description
要求输入一个以字符串方式存储的表达式,利用栈,能够计算表达式的值。表达式中允许的运算符为+,-,*,/,%,(,)。
函数原型: int CalValue(char *s); s存储表达式,函数返回值为表达式的值,表达式中的操作数为正整数。
输入: 15+(3-5)*7
输出:1
Input
Output
Sample Input
5+7*(25-12)/2-3
Sample Output
47
//
// Created by Legends丶Hu on 2020/2/4.
//
#include <iostream>
#include <cstring>
#include <cctype>
//#include "Stack.h"
using namespace std;
const int StackSize = 100;
template<class T>
class Stack {
private:
int top;
T data[StackSize];
public:
Stack();
void Push(T x);
T Pop();
T GetTop();
int Empty();
~Stack() {}
};
template<class T>
void Stack<T>::Push(T x) {
if (top == StackSize - 1) throw "Overflow";
data[++top] = x;
}
template<class T>
Stack<T>::Stack() {
top = -1;
}
template<class T>
T Stack<T>::Pop() {
if (Empty()) throw "Downflow";
return data[top--];
}
template<class T>
T Stack<T>::GetTop() {
return Empty() ? throw "Downflow" : data[top];
}
template<class T>
int Stack<T>::Empty() {
return top == -1;
}
//3*(4+2)/2-5
int compare(char c) {//优先级比较
switch (c) {
case '#':
return 0;
case '(':
return 1;
case '+':
case '-':
return 2;
case '*':
case '/':
case '%':
return 3;
}
}
int compute(int a, int b, char ch) {
int res;
switch (ch) {
case '+':
res = a + b;
break;
case '-':
res = a - b;
break;
case '/':
res = a / b;
break;
case '*':
res = a * b;
break;
case '%':
res = a % b;
break;
}
return res;
}
int MidCalValue(char *s) {
Stack<int> OPND;//操作数
Stack<char> OPTR;//操作符
OPTR.Push('#');
for (int i = 0; i < strlen(s);) {
if (isdigit(s[i])) {
int num = 0;
while (isdigit(s[i])) {
num = num * 10 + s[i] - '0';
i++;
}
OPND.Push(num);
} else {
//字符
if (s[i] == '(')OPTR.Push(s[i]);
else if (s[i] == ')') {
char ch = OPTR.Pop();
while (ch != '(') {
int a = OPND.Pop();
int b = OPND.Pop();
int x = compute(b,a,ch);
OPND.Push(x);
ch = OPTR.Pop();
}
} else {
char ch = OPTR.GetTop();
while (compare(ch) >= compare(s[i])) {
int a = OPND.Pop();
int b = OPND.Pop();
int x = compute(b,a,ch);
OPND.Push(x);
OPTR.Pop();
ch = OPTR.GetTop();
}
OPTR.Push(s[i]);
}
i++;
}
}
char ch;
while ((ch = OPTR.Pop()) != '#') {
int a = OPND.Pop();
int b = OPND.Pop();
int x = compute(b,a,ch);
OPND.Push(x);
}
return OPND.Pop();
}
void ConvertPost(char *str,char *res) {
Stack<char> s;
// str[strlen(str)] = '#';
s.Push('#');
int index = 0;
for (int i = 0; i < strlen(str);) {
if (isdigit(str[i])) {
while (isdigit(str[i])) {
res[index++] = str[i++];
}
res[index++]=' ';
} else {
if (str[i] == '(') {
s.Push(str[i]);
} else if (str[i] == ')') {
char ch = s.GetTop();
while (ch != '(') {
res[index++] = ch;
res[index++] = ' ';
s.Pop();
ch = s.GetTop();
}
s.Pop();
} else {
char ch = s.GetTop();
while (compare(ch) >= compare(str[i])) {
res[index++] = ch;
res[index++] = ' ';
s.Pop();
ch = s.GetTop();
}
s.Push(str[i]);
}
i++;
}
}
char ch = s.GetTop();
while ((ch = s.Pop()) != '#') {
res[index++] = ch;
res[index++] = ' ';
}
res[index] = '\0';
}
int PostCalValue(char *s) {
Stack<int> stack;
for(int i = 0; i < strlen(s); i++) {
if(isdigit(s[i])) {
int num = 0;
while (isdigit(s[i])) {
num = num * 10 + s[i] - '0';
i++;
}
stack.Push(num);
continue;
} else if(s[i] != ' '){
int a = stack.Pop();
int b = stack.Pop();
int x = compute(b,a,s[i]);
stack.Push(x);
}
}
return stack.Pop();
}
//3*(4+2)/2-5
//1 2 + 3 4 - *
//(1+1)*(3-4)
//5+7*(25-12)/2-3%3
int main() {
char str[100],s[100];
cin >> str;//
ConvertPost(str,s);
cout << MidCalValue(str) << endl;
/* cout << s << endl;
cout << PostCalValue(s) << endl;*/
return 0;
}