求前缀表达式的值(pat), 后缀表达式求解(leetcode)

26 篇文章 0 订阅
21 篇文章 0 订阅

前缀,中缀,后缀表达式 与 二叉树中的前,中,后序遍历一直
其中中缀表达式就说我们生活中用到的数学算式

中缀转后缀的一道编程题
http://blog.csdn.net/qq_26437925/article/details/49022895

后缀表达式求解
150 . Evaluate Reverse Polish Notation
https://leetcode.com/problems/evaluate-reverse-polish-notation/

leetcode不是太严谨
下面是一份ac代码,有待改进,主要是求解思路和用到的数据结构

typedef struct mydata{
    bool isOperator;
    string oper;
    int number;
}DataObj;

int func(DataObj d1,DataObj d2,DataObj op)
{
    if(op.oper == "+"){
        return d1.number + d2.number;
    }
    if(op.oper == "-"){
        return d1.number - d2.number;
    }
    if(op.oper == "*"){
        return d1.number * d2.number;
    }
    if(op.oper == "/"){
        return d1.number / d2.number;
    }
    return -1;
}

class Solution {
public:
    int evalRPN(vector<string>& tokens) {

        stack<DataObj> sta;

        int len = tokens.size();
        for(int i=0;i<len;i++){
            string str = tokens[i];
            DataObj obj;
            if(str == "+" || str == "-" || str == "*" || str == "/"){
                obj.isOperator = true;
                obj.oper = str;
            }else{
                stringstream ss;
                ss << str;
                int val = 0;
                ss >> val;
                obj.number = val;
                obj.isOperator = false;
            }

            if(obj.isOperator){
                DataObj d2 = sta.top();
                sta.pop();

                DataObj d1 = sta.top();
                sta.pop();

                DataObj tmp;
                tmp.isOperator = false;
                tmp.number = func(d1,d2,obj);

                sta.push(tmp);
            }else{
                sta.push(obj);
            }
        }
        while(!sta.empty())
            return sta.top().number;
        return -1;
    }
};
http://www.patest.cn/contests/mooc-ds/02-%E7%BA%BF%E6%80%A7%E7%BB%93%E6%9E%843

算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4。请设计程序计算前缀表达式的结果值。

输入格式说明:

输入在一行内给出不超过30个字符的前缀表达式,只包含+、-、*、\以及运算数,不同对象(运算数、运算符号)之间以空格分隔。

输出格式说明:

输出前缀表达式的运算结果,精确到小数点后1位,或错误信息“ERROR”。

样例输入与输出:

序号输入输出
1
+ + 2 * 3 - 7 4 / 8 4
13.0
2
/ -25 + * - 2 3 4 / 8 4
12.5
3
/ 5 + * - 2 3 4 / 8 2
ERROR
4
+10.23
10.2

主要是字符串处理 和 c++ stl(stack queue等)的应用

#include <cstdio>  
#include <sstream>  
#include <cstring>  
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <algorithm>
#include <sstream>
#include <cmath>

using namespace std;

#define  N 1000

char s[N];

struct mydata{
  double num;
  string sign;
};

double add(double a1, double a2)
{
  return a1 + a2;
}

double sub(double a1, double a2)
{
  return a1 - a2;
}

double cheng(double a1, double a2)
{
  return a1 * a2;
}

double chu(double a1, double a2)
{
  return a1 / a2;
}

double str2double(string s)
{
  double d;
  stringstream ss;
  ss << s;
  ss >> d;
  return d;
}

double ans;

deque<mydata> dque;

bool func()
{
  dque.clear();
  int len = strlen(s);
  int i;
  string stmp = "";
  mydata dt;

  for (i = 0; i < len; i++)
  {
    char c = s[i];

    if (i == len - 1) // 最后
    {
      if (stmp == "")
      {
        stmp += c;
      }
      else{
        stmp += c;
      }
      dt.sign = "-1";
      dt.num = str2double(stmp);
      dque.push_back(dt);
    }
    if ((c >= '0' && c <= '9') || c=='.')
    {
      stmp += c;
    }
    else if (c == '+' || c == '-')
    {
      stmp += c;
    }
    else if (c == '*' || c == '/')
    {
      stmp += c;
    }
    else //(c == ' ') // 空格
    {
      if (stmp != "")
      {
        if (stmp == "+" || stmp == "-" || stmp == "*" || stmp == "/")
        {
          dt.sign = stmp;
        }else{
          dt.sign = "-1";
          dt.num = str2double(stmp);
        }
        dque.push_back(dt);
      }
      stmp = "";
    }
  }

  deque<mydata> dque2;
  dque2.clear();
  int dsize = dque.size();
  if (dsize == 1)
  {
    if (dque.back().sign != "-1")
    {
      return false;
    }
    else{
      ans = dque.back().num;
      return true;
    }
  }
  if (dsize == 2)
  {
    return false;
  }
  while (!dque.empty())
  {
    /*  int dsize = dque.size();
      if (dsize >= 1)
      {*/
      mydata dt3 = dque.back();

      while (dt3.sign == "-1")
      {
        dque2.push_back(dt3);
        dque.pop_back();
        dt3 = dque.back();
      }
      dque.pop_back();

      mydata dt1 = dque2.back(); // 第1个数
      dque2.pop_back();
      mydata dt2 = dque2.back(); // 第2个数
      dque2.pop_back();

      double tmpc;
      if (dt3.sign == "+")
      {
        tmpc = add(dt1.num, dt2.num);
      }
      else if (dt3.sign == "-")
      {
        tmpc = sub(dt1.num, dt2.num);
      }
      else if (dt3.sign == "*")
      {
        tmpc = cheng(dt1.num, dt2.num);
      }
      else{ // 判断是否是 / 0
        if (dt2.num == 0)
          return false;
        tmpc = chu(dt1.num, dt2.num);
      }
      dt.num = tmpc;
      dt.sign = "-1";
      dque2.push_back(dt);
    //}
  }
  ans=dque2.back().num;
  return true;
}

int main()
{
  //freopen("in", "r", stdin);
  while (gets(s) != NULL)
  {
    if (func())
    {
      printf("%.1f", ans);
    }
    else{
      printf("ERROR");
    }
    printf("\n");
  }
  return 0;
}

// 下面是采用string 和 deque<>,string类处理更加简单

/*
http://www.patest.cn/contests/mooc-ds/02-%E7%BA%BF%E6%80%A7%E7%BB%93%E6%9E%843
02-线性结构3. 求前缀表达式的值(25)
string 和 deque<> 
*/
#include <iostream>  
#include <vector>  
#include <map>  
#include <set>  
#include <string>  
#include <stdio.h>
#include <string.h>
#include <algorithm>  
#include <sstream>
#include <iterator>
#include <unordered_map>
#include <queue>

using namespace std;

#define N 101 // 

deque<string> que;

double str2double(string s)
{
    stringstream ss;
    ss << s;
    double d;
    ss >> d;
    return d;
}

char getOperate(string s)
{
    if (s.size() == 1)
    {
        if (s[0] == '+')
            return '+';
        else if (s[0] == '-')
            return '-';
        else if (s[0] == '*')
            return '*';
        else if (s[0] == '/')
            return '/';
        else
            return '0';
    }
    return '0';
}

double cal(double d1, double d2, char c)
{
    switch (c){
    case '+':
        return d1 + d2;
        break;
    case '-':
        return d1 - d2;
        break;
    case '*':
        return d1 * d2;
        break;
    case '/':
        return d1 / d2;
        break;
    }
}

int main()
{
    //freopen("in", "r", stdin);
    string s;
    while (getline(cin, s))
    {
        while (!que.empty())
            que.pop_back();
        istringstream iss(s);
        string st;
        while (iss >> st)
        {
            que.push_back(st);
        }
        int lenq = que.size();
        if (lenq == 1)
        {
            if (getOperate(que.front()) == '0')
            {
                double d = str2double(que.front());
                printf("%.1lf\n", d);
            }
            else{
                printf("ERROR\n");
            }
        }
        else if (lenq == 2)
        {
            printf("ERROR\n");
        }
        else{
            bool flag = true;
            deque<double> qtmp;
            while (!qtmp.empty())
                qtmp.pop_back();
            while (!que.empty() && flag)
            {
                string top = que.back();
                que.pop_back();
                if (getOperate(top) == '0')
                {
                    qtmp.push_back(str2double(top));
                }
                else{
                    char ope = getOperate(top);
                    if ((int)qtmp.size() >= 2)
                    {
                        double num1 = qtmp.back();
                        qtmp.pop_back();
                        double num2 = qtmp.back();
                        qtmp.pop_back();

                        if (ope == '/' && num2 == 0)
                        {
                            flag = false;
                        }
                        else{
                            double tmprs = cal(num1, num2, ope);
                            qtmp.push_back(tmprs);
                        }
                    }
                    else{
                        flag = false;
                    }
                }
            } // while
            if (flag == false)
                printf("ERROR\n");
            else
                printf("%.1lf\n", qtmp.front());
        } // else
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值