思路:
所包含的運算符有‘+’,‘-’,‘*’,‘/’,‘(’,‘)’。
(1)建立兩個棧,一個用來存儲操作數,另一個用來存儲運算符, 開始時在運算符棧中先壓入‘/0’,一個表達式的結束符。
(2)然后從左至右依次讀取表達式中的各個符號(操作數或者運算符);
(3)如果讀到的是操作數直接存入操作數棧;
(4)如果讀到的是運算符,則作進一步判斷:
若讀到的是‘/0’結束符,而且此時運算符棧的棧頂元素也是‘/0’結束符,則運算結束,輸出操作數棧中的元素即為最后結果。
若讀到的是‘(’或者讀到的運算符的優先級比目前的運算符棧中的棧頂元素的優先級高,則將運算符直接存入運算符棧,繼續讀表達式中的下一個符號,重復步驟(3)和(4);
若讀到的是‘)’,而且此時運算符棧的棧頂元素是‘(’結束符,則將運算符棧中的棧頂元素退出來,繼續讀表達式中的下一個符號,重復步驟(3)和(4);
若讀到的運算符的優先級等於或小於之前的運算符的優先級,則從操作數中退出2個,從運算符中退出一個進行運算,將運算結果存入操作數棧;再把之前讀到的運算符與目前的運算符棧頂比較,重復步驟(4)(即現在不讀下一個元素);
#include <iostream>
#include <stack>
using namespace std;
double toNum(char*s, int &k)
{
int flag = 0;
double x = 0.0, y = 0.1;
while (s[k] >= '0'&&s[k] <= '9' || s[k] == '.')
{
if (s[k] >= '0'&&s[k] <= '9')
{
if (flag == 0)
x = x * 10 + s[k] - '0';
else
{
x = x + y*(s[k] - '0');
y = y*0.1;
}
}
else
{
flag = 1;
}
k = k + 1;
}
return x;
}
int priority(char c)
{
int k;
switch (c)
{
case '*':k = 2; break;
case '/':k = 2; break;
case '+':k = 1; break;
case '-':k = 1; break;
case '(':k = 0; break;
case ')':k = 0; break;
default:k = -1; break;
}
return k;
}
int main()
{
stack<double> sv;
stack<char> sp;
char c;
int k = 0, flag = 1;
double x, y;
sp.push('\0');
char *s = new char[100];
cout << "請輸入算式:" << endl;
cin >> s;
c = s[k];
while (flag)
{
if (c >= '0'&&c <= '9' || c == '.')
{
sv.push(toNum(s, k));
}
else if (c == '\0'&& sp.top() == '\0')
{
flag = 0;
}
else if (c == '(' || (priority(c) > priority(sp.top())))
{
sp.push(c);
k++;
}
else if (c == ')'&& sp.top() == '(')
{
sp.pop();
k++;
}
else if (priority(c) <= priority(sp.top()))
{
x = sv.top();
sv.pop();
y = sv.top();
sv.pop();
c = sp.top();
sp.pop();
switch (c)
{
case '+':y = x + y; break;
case '-':y = y - x; break;
case '*':y = x*y; break;
case '/':y = y / x; break;
}
sv.push(y);
}
c = s[k];
}
cout << sv.top() << endl;
return 0;
}
