a017.
五則運算
| From: [203.64.46.82] |
發表日期
:
2012-12-25 15:17
我把式子先轉成 postfix 表示後再計算,符號的優先順序自己測都正常,不知哪裡出問題,想請教一下@@
#include <iostream>
#include <sstream>
#include <cctype>
#include <stack>
using namespace std;
int isp(char);
int icp(char);
bool transform_to_postfix(const string&, string&);
int count(const string&);
int main()
{
string input;
while(getline(cin, input))
{
string postfix = "";
transform_to_postfix(input, postfix);
//cout << postfix << endl;
cout << count(postfix) << endl;
}
return 0;
}
int isp(char ch)
{
switch(ch)
{
case ')' :
return 19;
case '*':
case '/':
case '%':
return 13;
case '+':
case '-':
return 12;
case '(':
return 0;
}
}
int icp(char ch)
{
switch(ch)
{
case ')' :
return 19;
case '*':
case '/':
case '%':
return 13;
case '+':
case '-':
return 12;
case '(':
return 20;
}
}
bool transform_to_postfix(const string& input, string& output)
{
stack<char>oprtr;
istringstream sin(input);
char ch;
while(sin.get(ch) && !sin.eof())
{
if(ch != ' ')
{
if(isdigit(ch))
{
output += ch;
while(sin.get(ch) && ch != ' ')
output += ch;
output += ' ';
}
else if(oprtr.empty())
oprtr.push(ch);
else
{
if(ch == ')')
{
while(oprtr.top() != '(')
{
output += oprtr.top();
output += ' ';
oprtr.pop();
}
oprtr.pop();
}
else if(icp(ch) <= isp(oprtr.top()))
{
output += oprtr.top();
output += ' ';
oprtr.pop();
oprtr.push(ch);
}
else
oprtr.push(ch);
}
}
}
while(!oprtr.empty())
{
output += oprtr.top();
output += ' ';
oprtr.pop();
}
return 1;
}
int count(const string& postfix_input)
{
stack<int> oprnd;
istringstream sin(postfix_input);
char ch;
while(sin.get(ch) && !sin.eof())
{
if(ch != ' ')
{
if(isdigit(ch))
{
sin.putback(ch);
int token;
sin >> token;
oprnd.push(token);
}
else if(ispunct(ch))
{
int oprnd2 = oprnd.top();
oprnd.pop();
int oprnd1 = oprnd.top();
oprnd.pop();
if(ch == '+')
oprnd.push( oprnd1 + oprnd2 );
else if(ch == '-')
oprnd.push( oprnd1 - oprnd2 );
else if(ch == '*')
oprnd.push( oprnd1 * oprnd2 );
else if(ch == '/')
oprnd.push( oprnd1 / oprnd2 );
else if(ch == '%')
oprnd.push( oprnd1 % oprnd2 );
}
}
}
return oprnd.top();
}