题目描述
大家可以忽略 我就是想记录一下
小数版表达式求值
(根据老师要求写的自己的mystack)
样例
#include <iostream>
#include <cstring>
#include <stack>
#include <unordered_map>
#include <cmath>
using namespace std;
unordered_map<char, int> ps = { {'+',1}, {'-',1}, {'*',2},{'/',2} };
class CMyStack {
private:
double* m_pTop; // Top pointer of stack
int m_iSize; // Number of actual elements
int m_iCapacity; // Capacity of stack
public:
CMyStack(int size) : m_iSize(0), m_iCapacity(size) {
m_pTop = new double[size];
}
~CMyStack() {
delete[] m_pTop;
}
double Pop() {
if (isEmpty()) {
cout << "Stack is empty." << endl;
return 0;
}
return m_pTop[-- m_iSize];
}
double Peek() {
if (isEmpty()) {
cout << "Stack is empty." << endl;
return 0;
}
return m_pTop[m_iSize - 1];
}
bool Push(double ch) {
if (isFull()) {
cout << "Stack is full." << endl;
return false;
}
m_pTop[m_iSize++] = ch;
return true;
}
bool isEmpty() {
return m_iSize == 0;
}
bool isFull() {
return m_iSize == m_iCapacity;
}
int GetSize() {
return m_iSize;
}
void Clear() {
while (!isEmpty()) {
Pop();
}
}
};
class CExpression {
private:
string expression;
CMyStack num;
stack<char> op;
public:
CExpression(const string& expr) : num(expr.size())
{
expression = expr;
}
void eval()
{
double b = num.Peek(); num.Pop();
double a = num.Peek(); num.Pop();
char c = op.top(); op.pop();
double x;
if (c == '+') x = a + b;
else if (c == '-') x = a - b;
else if (c == '*') x = a * b;
else if (c == '/') x = a / b;
num.Push(x);
}
double Value() {
int len = expression.size();
for (int i = 0; i < len; i++)
{
auto c = expression[i];
if (isdigit(c))
{
double x = 0;
int j = i;
while (j < len && isdigit(expression[j]))
{
x = x * 10 + expression[j++] - '0';
}
i = j;
if (expression[i] == '.')
{
int j = i + 1, cnt = 1;
while (j < len && isdigit(expression[j]))
{
x = x + (double)(expression[j] - '0') / pow(10 ,cnt);
j ++;
cnt ++;
}
i = j - 1;
// cout << x << endl;
num.Push(x);
}
else
{
i = j - 1;
// cout << x << endl;
num.Push(x);
}
}
else if (c == '(') op.push(c);
else if (c == ')')
{
while (op.top() != '(') eval();
op.pop();
}
else
{
while (op.size() && op.top() != '(' && ps[op.top()] >= ps[c]) eval();
op.push(c);
}
}
while (op.size()) eval();
return num.Peek();
}
void SetExpression(const string& expr) {
expression = expr;
num.Clear();//清除数字栈
while (!op.empty()) op.pop();//清除字符栈
}
friend ostream& operator<<(ostream& os, const CExpression& expr) {
os << expr.expression;
return os;
}
};
int main() {
CExpression expr("50.3-20.12+8*8/2");
cout << expr << " = " << expr.Value() << endl; // 50.3-20.12+8*8/2 = 62.18
expr.SetExpression("55.99-88.11+77.12");
cout << expr << " = " << expr.Value() << endl; // 55.99-88.11+77.12 = 45
expr.SetExpression("(39+11)*30+10/5");
cout << expr << " = " << expr.Value() << endl; // (39+11)*30+10/5 = 1502
expr.SetExpression("39+12*(47+33)");
cout << expr << " = " << expr.Value() << endl; // 39+12*(47+33) = 999
expr.SetExpression("20/(112-(10*1.2))/10-1.01");
cout << expr << " = " << expr.Value() << endl; // 20/(112-(10*1.2))/10-1.01 = -0.99
expr.SetExpression("20/(112-10*1.2)/10-1.01");
cout << expr << " = " << expr.Value() << endl; // 20/(112-10*1.2)/10-1.01 = -0.99
cout << "ENDING..." << endl;
return 0;
}