简单计算器-栈stack和队列queue

一、技术总结

  1. 主要是一个中缀表达式,然后求值,一些加减乘除
  2. 第一步是把中缀表达式转化为后缀表达式
  3. 然后就是计算后缀表达式,计算出结果
  4. 主要是两个函数,一个是转化函数Change()还有一个是计算函数Cal()

二、参考代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<stack>
#include<queue>
#include<map>
using namespace std;

struct node{
    double num;//操作数
    char op;//操作符
    bool flag;//true表示操作数,false表示操作符
}; 

string str;
stack<node> s;//操作符栈
queue<node> q;//后缀表达式序列
map<char, int> op;

void Change(){
    double num;
    node temp;
    for(int i = 0; i < str.length(); ){
        if(str[i] >= '0' && str[i] <= '9'){//如果是数字
            temp.flag = true;//标记是数字
            temp.num = str[i++] - '0';//记录这个操作数的第一个数位
            while(i < str.length() && str[i] >= '0' && str[i] <= '9'){
                temp.num = temp.num * 10 + (str[i] - '0');//更新这个操作数
                i++;
            }
            q.push(temp);//将操作数压入后缀表达式的队列
        }else{//如果是操作符
            temp.flag = false;//标记是操作符
            //只要操作符栈的栈顶元素比该操作符优先级高
            //就把操作符栈栈顶元素弹出到后缀表达式队列中
            while(!s.empty() && op[str[i]] <= op[s.top().op]){
                q.push(s.top());
                s.pop();
            }
            temp.op = str[i];
            s.push(temp);//把该操作符压入操作符栈中
            i++;
        }
    }
    while(!s.empty()){
        q.push(s.top());
        s.pop();
    }
} 

double Cal(){//计算后缀表达式
    double temp1, temp2;
    node cur, temp;
    while(!q.empty()) {//只要后缀表达式队列非空
        cur = q.front();//cur记录队首元素
        q.pop();
        if(cur.flag == true) s.push(cur);//如果是操作数直接压入栈
        else{//如果是操作符
            temp2 = s.top().num; //弹出第二操作数
            s.pop();
            temp1 = s.top().num;//弹出第一操作数
            s.pop();
            temp.flag = true;//临时记录操作数
            if(cur.op == '+') temp.num = temp1 + temp2;
            else if(cur.op == '-') temp.num = temp1 - temp2;
            else if(cur.op == '*') temp.num = temp1 * temp2;
            else temp.num = temp1 / temp2;
            s.push(temp);//把操作数压入栈
        }
    }
    return s.top().num;//栈顶元素就是最后表达式的值
}

int main(){
    op['+'] = op['-'] = 1;
    op['*'] = op['/'] = 2;
    while(getline(cin, str), str != "0"){
        for(auto it = str.end(); it != str.begin(); it--){
            if(*it == ' ') str.erase(it);//把表达式中的所有空格全部去掉
        }
        while(!s.empty()) s.pop();//初始化栈
        Change();
        printf("%.2f\n", Cal());
    }
    return 0;
} 

原文地址:https://www.cnblogs.com/tsruixi/p/12246875.html

时间: 2024-11-05 16:30:38

简单计算器-栈stack和队列queue的相关文章

利用栈Stack实现队列(Queue)

实现说明: 入队时,将元素压入s1; 出队时,判断s2是否为空,如不为空,则直接弹出顶元素:如为空,则将s1的元素逐个"倒入"s2,把最后一个元素弹出并出队; 这个思路,避免了反复"倒"栈,仅在需要时才"倒"一次. package com.knowledgeStudy.threadLocal; import java.util.Stack; public class MyQueue { Stack<Object> s1 = new S

自定义栈Stack 和 队列Queue

自定义栈 接口 package com.test.custom; public interface IStack<E> { E pop(); void push(E e); E peek(); int size(); boolean empty(); void clear(); } 实现类 package com.test.custom; import java.util.ArrayList; import java.util.EmptyStackException; import java.

hdu-1237简单计算器(栈的运用)

http://acm.hdu.edu.cn/showproblem.php?pid=1237 简单的栈的运用. 首先将数字和运算符分离,分别保存在两个数组中,然后按原来的式子的顺序,首先将第一个数和第一个运算符分别压 如个自的栈,然后判取出两个栈头部的元素,判断符号,如果是乘除就用当前数值乘取出的数字(优先),然后将乘后的数压入栈, 如果是加则将数和取出的数按原序入栈,如果减,就把新的数变负,将数和取出的数按原序入栈. 最后栈中所有元素的和就是结果. 1 #include<stdio.h> 2

简单计算器(栈)

欢迎参加——每周六晚的BestCoder(有米!) 简单计算器 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 14873    Accepted Submission(s): 5061 Problem Description 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值. Input 测试输入包含若干测试

HDU 1237 简单计算器(栈)

题目链接 Problem Description 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值. Input 测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔.没有非法表达式.当一行中只有0时输入结束,相应的结果不要输出. Output 对每个测试用例输出1行,即该表达式的值,精确到小数点后2位. Sample Input 1 + 2 4 + 2 * 5 - 7 / 11 0 Sample Output 3.00

HDU 1237 简单计算器(stack)

Problem Description 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值. Input 测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔.没有非法表达式.当一行中只有0时输入结束,相应的结果不要输出. Output 对每个测试用例输出1行,即该表达式的值,精确到小数点后2位. Sample Input 1 + 2 4 + 2 * 5 - 7 / 11 0 Sample Output 3.00 13.3

C++算法之 自己写一个简单的栈Stack

// Stack.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> using namespace std; enum{COUNT = 8}; typedef int TYPE; class CStack { TYPE m_pData[COUNT]; int m_nTop; int m_nCount; public: bool isFull() { return m_nTop+1>= m_n

简单的栈和队列

1 /* 2 入门之栈(Stack)和队列(Queue) 3 在C++中STL中预置了<stack>和<queue> 4 简单介绍栈和队列的思想和使用方法 5 栈:先入后出(LIFO),可以理解为将球放进一个一段封闭的管子,只能从入口区出,先进的球只能最后出来 6 队列:先入先出(FIFO),可以理解为将球放进不封闭的管子,球从另一端出来,先进的球先出 7 常见应用:栈可以用于深搜(DFS),队列可以用于宽搜(BFS) 8 只有看看例子就可以很好的理解栈和队列了,简单的先介绍这些

数据结构之——链表(list)、队列(queue)和栈(stack)

在前面几篇博文中曾经提到链表(list).队列(queue)和(stack),为了更加系统化,这里统一介绍着三种数据结构及相应实现. 1)链表 首先回想一下基本的数据类型,当需要存储多个相同类型的数据时,优先使用数组.数组可以通过下标直接访问(即随机访问),正是由于这个优点,数组无法动态添加或删除其中的元素,而链表弥补了这种缺陷.首先看一下C风格的单链表节点声明: 1 typedef struct _ListNode{ 2 int val; 3 struct _ListNode *next; 4