題目鏈接: http://ac.jobdu.com/problem.php?pid=1019
題目分析:
使用兩個棧,一個存儲數字數據,一個存儲操作符號。判斷*和/的時候,不入棧,直接通過判斷計算前後數字乘除法操作後的值,順序入數字棧。操作符棧最後只存儲+和-符號。
都入棧完畢之後,由於是中綴表達式計算,計算順序從左至右,這就需要將棧中數據逆置,採用導出到數組的方法。導出完畢後,依次從左至右開始計算,即可解決。
源代碼:
#include <iostream>
#include <iomanip>
#include <stack>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
int main()
{
stack<double> SD; //數字棧
stack<char> SO; //操作符棧
double left, right; //退棧時存儲棧頭數字
int num; //輸入數字
char op; //輸入操作符
double data[1000]; //數字數組
char operate[1000]; //操作符數組
while (cin>>num) //讀入開始數字
{
op = getchar(); //讀取數字後輸入的字符
if (num == 0 && op == '\n') //輸入0後,退出
{
break;
}
SD.push(num);
while (op == ' ') //數字後要跟空格
{
op = getchar(); //讀取空格後的操作符
if (op == '\n') //輸入回車後,程序結束
{
break;
}
if (!SO.empty() && (SO.top() == '*' || SO.top() == '/'))
{
right = SD.top();
SD.pop();
left = SD.top();
SD.pop();
if (SO.top() == '*')
{
SD.push(left * right);
}
if (SO.top() == '/')
{
SD.push(left / right);
}
SO.pop();
}
SO.push(op);
cin>>num;
SD.push(num);
op = getchar(); //下一輪循環判斷
}
if (SO.top() == '*' || SO.top() == '/')
{
right = SD.top();
SD.pop();
left = SD.top();
SD.pop();
if (SO.top() == '*')
{
SD.push(left * right);
}
else if (SO.top() == '/')
{
SD.push(left / right);
}
SO.pop();
}
//將堆棧數據保存到保存到數組中,從左向右計算
int i = 0;
int oplength, datalength; //棧內數據長度
int optop, datatop;
while (!SO.empty())
{
operate[i++] = SO.top();
SO.pop();
}
oplength = i;
optop = i - 1;
i = 0;
while (!SD.empty())
{
data[i++] = SD.top();
SD.pop();
}
datalength = i;
datatop = i - 1;
for (int j = optop; j >= 0; j--)
{
if (operate[j] == '+')
{
data[datatop - 1] = data[datatop] + data[datatop - 1];
datatop --;
}
else if (operate[j] == '-')
{
data[datatop - 1] = data[datatop] - data[datatop - 1];
datatop --;
}
}
cout.setf(ios::fixed);
cout<<setprecision(2)<<data[0]<<endl;
}
return 0;
}