现在的位置: 首页 > 综合 > 正文

小小后缀计算器

2013年08月08日 ⁄ 综合 ⁄ 共 1886字 ⁄ 字号 评论关闭

以前在《The c programming language》 里面看到了个后缀计算器,输入是后缀表达式,输出计算结果。当时还不知道如何把用户容易使用的表达式(中缀)转换成后缀。

后来看了《Data structures and algorithm analysis》,发现 栈 这一章里面讲了一种算法,不是很复杂。于是当时我就把两者组合起来,做了一个很不错的后缀计算器(至少从编程风格上来说)我感觉istringstream是很好用的,相比c中getchar()ungetc()自行管理缓冲区要方便,更不容易出错。

#include <cctype>
#include <sstream>
#include <string>
#include <stack>
#include <iostream>

using namespace std;

int cmp(char,char);

string inTopost(string infix)
{
	istringstream in(infix);
	ostringstream out;
	stack<char> op;
	char c;

	while (in >> c)
	{
		if (c == '(')
			op.push(c);
		else if (c == ')')
		{
			while (!op.empty() && op.top() != '(')
			{
				out << op.top() << " ";
				op.pop();
			}
			if (!op.empty())
				op.pop();	//c == '('
		}
		else if (c == '+' || c == '-' || c =='*' || c == '/')
		{
			//cmp returns 1 if op.top() >= c
			while (!op.empty() && cmp(c,op.top()))
			{
				out << op.top() << " ";
				op.pop();
			}
			op.push(c);
		}
		else if (isdigit(c))
		{
			in.putback(c);
			int n;
			in >> n;
			out << n << " ";
		}
		else
			cout << "Unkown format" << endl;
	}
	while (!op.empty())
	{
		out << op.top() << " ";
		op.pop();
	}
	return out.str();
}
int cmp(char c1,char c2)
{
	switch (c1)
	{
		case '-':
		case '+': return (c2 == '(') ? 0 : 1;
				  break;
		case '/':
		case '*': if (c2 == '*' || c2 == '/')
					  return 1;
				  else
					  return 0;
				  break;
		default: cout << "Unknown OPTR" << endl;
	}
}

#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream>
#include <stack>

using namespace std;
string inTopost(string infix);


int main(int argc, char *argv[])
{
    bool quit = false;
    double op, op2;

    stack<double>  s1;
    string infix, postfix, cmd;
    cout << "Input infix expression you want to calculate:";
    getline(cin,infix,'\n');
    postfix = inTopost(infix);
    istringstream in(postfix);
    while (in >> cmd)
    {
        switch(cmd[0])
        {
            case '+':
                op = s1.top();
                s1.pop();
                op2 = s1.top();
                s1.pop();
                s1.push(op + op2);
                break;
            case '*':
                op = s1.top();
                s1.pop();
                op2 = s1.top();
                s1.pop();
                s1.push(op * op2);
                break;
            case '-':
                op2 = s1.top();
                s1.pop();
                op = s1.top();
                s1.pop();
                s1.push(op - op2);
                break;
            case '/':
                op2 = s1.top();
                s1.pop();
                if(op2)
                {
                    op = s1.top();
                    s1.pop();
                    s1.push(op / op2);
                }
                else
                    cout << "\nError: division by zero!";
                break;
            default:
                    istringstream in2(cmd);
                    in2 >> op;
                    s1.push(op);
            }
      }
      cout << s1.top() << endl
;
    system("PAUSE");
    return EXIT_SUCCESS;
}

抱歉!评论已关闭.