设为首页 加入收藏

TOP

【1】简单计算器(栈)
2019-03-13 18:08:34 】 浏览:100
Tags:简单 计算器

第一篇博客嘎嘎

问题描述:读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。

思路:建立两个栈,分别是:运算符栈,用于中缀表达式转化为后缀表达式;操作数栈,用于后缀表达式的计算

#include <iostream>
#include <cstdio>
#include <vector>
#include <stack>
#include <cstring>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
 
struct stNode
{
  int nType; //元素的类型,0操作数,1操作符
  double nNum; //操作数
  char cOp; //操作符
};
 
stack<char> sop; //运算符栈,用于中缀表达式转换成后缀表达式
stack<double> sNum; //操作数栈,用于后缀表达式的计算
char cExp[1024]; //读入的字符表达式
vector<stNode> SuffixExp; //后缀表达式
 
inline float GetNum(const char* p, int& k)
{
  int n = atoi(p);
  k = 0;
  while (isdigit(p[k]))
    ++k;
  return n;
}
 
inline int get_ip(char c) //获取栈内优先级
{
  switch (c)
  {
  case '#':
    return 0;
  case '+':
  case '-':
    return 3;
  case '*':
  case '/':
    return 5;
  }
  return 99;
}
 
inline int get_op(char c) //获取栈外优先级
{
  switch (c)
  {
  case '#':
    return 0;
  case '+':
  case '-':
    return 2;
  case '*':
  case '/':
    return 4;
  }
  return 99;
}
 
int main(void)
{
  memset(cExp, 0, sizeof(cExp)); //初始化栈
  while(cin.getline(cExp, 1024))
  {
  //读入字符表达式
  if(strlen(cExp)==1 && cExp[0]=='0') break;
  strcat(cExp, "#");
  while (!sop.empty()) //清空操作符栈
    sop.pop();
  sop.push('#'); //放入界定符
 
  //将中缀表达式转化成后缀表达式
  char *p = cExp;
  while (p[0] != '\0')
  {
    if (p[0] == ' ') //空格跳过
    {
      ++p;
      continue;
    }
    if (isdigit(p[0]))
    {
      //数字输出到后缀表达式
      int k;
      double n = GetNum(p, k);
      stNode stTemp;
      stTemp.nType = 0;
      stTemp.nNum = n;
      stTemp.cOp = 0;
      SuffixExp.push_back(stTemp);
      p += k;
    }
    else
    {
      char ch1 = p[0];
      char ch2 = sop.top();
      if (get_op(ch1) > get_ip(ch2))
      {
        sop.push(ch1);
        ++p;
      }
      else if (get_op(ch1) < get_ip(ch2))
      {
          //输出到后缀表达式
        stNode stTemp;
        stTemp.nType = 1;
        stTemp.nNum = 0;
        stTemp.cOp = ch2;
        SuffixExp.push_back(stTemp);
        sop.pop();
      }
      else
      {
        sop.pop();
        ++p;
      }
    }
  }
 
  //后缀表达式的计算
  while (!sNum.empty()) //清空操作数栈
    sNum.pop();
  for (int i = 0; i < (int)SuffixExp.size(); ++i)
  {
    if (SuffixExp[i].nType == 0)
      sNum.push(SuffixExp[i].nNum);
    else
    {
      double y = sNum.top();
      sNum.pop();
      double x = sNum.top();
      sNum.pop();
      switch (SuffixExp[i].cOp)
      {
      case '+':
        x += y;
        break;
      case '-':
        x -= y;
        break;
      case '*':
        x *= y;
        break;
      case '/':
        x /= y;
        break;
      }
      sNum.push(x);
    }
  }
  printf("%.2f\n", sNum.top()); //输出结果
  return 0;
  }
}

 知识点:atoi()、memset()【https://blog.csdn.net/qq_27522735/article/details/53374765】、printf("%.2f\n", x)【保留两位小数】

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇BZOJ3028: 食物(生成函数) 下一篇cf438E. The Child and Binary Tr..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目