四则运算(带括号)、栈应用

标签: 四则运算 栈应用
6人阅读 评论(0) 收藏 举报
分类:

程序小白,希望和大家多交流,共同学习

//使用两个栈,一个存储数字,一个存储运算符
//将给定的表达式(没有括号)变成后缀式,然后利用两个栈求出表达式的值
//为方便运算,先给定优先级'#'、'('、'+-'、'*/'、'^'
//所有的
#include<iostream>
#include<math.h>
using namespace std;

struct NodeDigit
{
    int data;
    NodeDigit *next;
};
typedef NodeDigit *DigitStack;

struct NodeOperator
{
    char data;
    NodeOperator *next;
};
typedef NodeOperator *OperatorStack;

//充分使用方法重用
//初始化
void init(DigitStack &ds);
void init(OperatorStack &os);
//进栈
void push(DigitStack &ds, int data);
void push(OperatorStack &os, char data);
//出栈
int pop(DigitStack &ds);
char pop(OperatorStack &os);
//判断为空
bool isEmpty(DigitStack ds);
bool isEmpty(OperatorStack os);
//判断满
bool isFull(DigitStack ds);
bool isFull(OperatorStack os);
//得到栈顶
int getTop(DigitStack ds);
char getTop(OperatorStack os);
//放回优先级
int priority(char ch);
//算后缀式,判断左多
int compute(DigitStack &ds, OperatorStack &os);
//锁定输入运算符
bool isOperator(char ch);

int main()
{
    DigitStack ds;
    OperatorStack os;
    init(ds);
    init(os);
    //错误状况:有空格,除数为零,非法字符输入,连续运算符输入,括号不匹配(左多右多)
    push(os, '#');
    char ch;
    char divide = '#';//记录除号,判断除数是否零
    bool op;//记录是否是运算符,判断两次输入是否都是运算符
    bool match = true;
    while (true)
    {
        if (!isOperator(ch = getchar()))
        {
            cout << "非法运算符 " << ch << endl;
            break;
        }

        if (ch == '=')//以'='作为截止符
        {
            while (getTop(os) != '#')
            {
                if (getTop(os) == '(')
                {
                    cout << "括号不匹配,左多\n";
                    break;
                }
                compute(ds, os);
            }
            if (getTop(os) != '(')
            {
                cout << pop(ds) << endl;
            }

            break;
        }

        if (ch == '/')//出栈可能会比较慢,直接将除号保存
        //由于初始化不是除号,所以下面的判断是对除号后紧接着数字的判断
        {
            divide = '/';
        }

        //输入的第一个字符是数字,就将字符推回输入流。
        //定义一个整型,用来读取一个完整的数字
        if (ch >= '0' && ch <= '9')
        {
            op = false;
            cin.putback(ch);
            int digit = 0;
            cin >> digit;
            if (divide == '/')
            {
                if (digit == 0)
                {
                    cout << "除数不能为零\n";
                    break;
                }
                else
                    divide = '#';
            }
            push(ds, digit);
        }

        else if (ch == '(')
        {
            push(os, ch);
        }

        else if (ch == ')')
        {
            while (getTop(os) != '(')
            {
                if (getTop(os) == '#')
                {
                    cout << "括号不匹配,右多\n";
                    match = false;
                    break;
                }
                compute(ds, os);
            }

            if (!match)
            {
                break;
            }
            pop(os);//将匹配的(抛出
        }

        else//不是字符那就是运算符,对于运算符,要么计算,要么入栈
            //排除括号的状况
        {
            if (op && ch != '(' && ch != ')')//先判断,那么判断的就是上一次的op状况
            {
                cout << "非法输入:连续两次输入运算符 " << ch << endl;
                break;
            }
            op = true;//再赋值,赋值的是这一次的状况
            //优先级较高者直接进栈
            //否则就计算
            //这是一个循环
            //最后将新的运算符入栈
            while (priority(ch) <= priority(getTop(os)))
            {
                compute(ds, os);
            }
            push(os, ch);
        }
    }
    return 0;
}

//初始化
void init(DigitStack &ds)
{
    //栈要封底
    ds = NULL;
}
void init(OperatorStack &os)
{
    os = NULL;
}
//进栈
void push(DigitStack &ds, int data)
{
    if (isFull(ds))
    {
        cout << "数字栈已满,无法进栈\n";
    }
    else
    {
        NodeDigit *newNode = new NodeDigit;
        newNode -> data = data;
        newNode -> next = ds;
        ds = newNode;
    }
}
void push(OperatorStack &os, char data)
{
    if (isFull(os))
    {
        cout << "运算符栈已满,无法进栈\n";
    }
    else
    {
        NodeOperator *newNode = new NodeOperator;
        newNode -> data = data;
        newNode -> next = os;
        os = newNode;
    }
}
//出栈
int pop(DigitStack &ds)
{
    if (isEmpty(ds))
    {
        cout << "数字栈已空,无法出栈\n";
        return 0;
    }
    NodeDigit *delosde = ds;
    int data = delosde -> data;
    ds = ds -> next;
    delete delosde;
    return data;
}
char pop(OperatorStack &os)
{
    if (isEmpty(os))
    {
        cout << "运算符栈已空,无法出栈\n";
        return ' ';
    }

    NodeOperator *delosde = os;
    char data = delosde -> data;
    os = os -> next;
    delete delosde;
    return data;
}
//判断为空
bool isEmpty(DigitStack ds)
{
    return ds == NULL;
}
bool isEmpty(OperatorStack os)
{
    return os == NULL;
}
//判断满
bool isFull(DigitStack ds)
{
    NodeDigit *newNode = new NodeDigit;
    if (newNode == NULL)
    {
        delete newNode;
        return true;
    }
    else
        return false;
}
bool isFull(OperatorStack os)
{
    NodeOperator *newNode = new NodeOperator;
    if (newNode == NULL)
    {
        delete newNode;
        return true;
    }
    else
        return false;
}
//得到栈顶
int getTop(DigitStack ds)
{
    if (isEmpty(ds))
    {
        cout << "数字栈已空,无栈顶数字\n";
        return 0;
    }
    return ds -> data;
}
char getTop(OperatorStack os)
{
    if (isEmpty(os))
    {
        cout << "运算符栈已空,无栈顶运算符\n";
        return ' ';
    }
    return os -> data;
}
//放回优先级
int priority(char ch)
{
    switch (ch)
    {
    case '#':
        return 0;
    case '(':
        return 1;
    case '+':
    case '-':
        return 2;
    case '*':
    case '/':
        return 3;
    case '^':
        return 4;
    }
}
//算后缀式,判断左多
int compute(DigitStack &ds, OperatorStack &os)
{
    int d2 = pop(ds);
    int d1 = pop(ds);
    char op = pop(os);
    double result;
    switch (op)
    {
    case '+':
        result = d1 + d2; break;
    case '-':
        result = d1 - d2; break;
    case '*':
        result = d1 * d2; break;
    case '/':
        result = d1 / d2; break;
    case '^':
        result = pow(d1, d2); break;
    }
    //cout << d1 << op << d2 << "=" << result <<endl;
    push(ds, result);
    return true;
}
//锁定输入运算符
bool isOperator(char ch)
{
    return (ch == '+' || ch == '-' || ch == '*' 
        || ch == '/' || ch == '^' || ch == '='
        || (ch >= '0' && ch <= '9') || ch == '('
        || ch == ')');
}

//2+5*6+7*9*10^2+6=
//2+5*6+7/0*10^2+6=
//2+5*6+7*10^2+6
//2+5*6+7**9*10^2+6=
//5*6+(7+8*6)+7^2-5=
//5*6+(7+8*6))+7^2-5=
//5*6+((7+8*6)+7^2-5=
//(5*6+(7+8*6))+7^2-5=
查看评论

使用栈实现的带括号的四则运算

  • 2012年01月13日 18:14
  • 6KB
  • 下载

用栈的知识实现四则运算(带括号的加减乘除)

#include #include #include #include using namespace std; void size_yunsuan(string input,string &a) {...
  • qq_22335577
  • qq_22335577
  • 2015-04-12 10:20:06
  • 1284

c++栈之带括号的四则运算

题目要求:          实现带括号的四则运算。 实现思想:        创建两个栈,保存数字和符号,根据运算级的高低,确定弹栈以及压栈(栈为模板类,因为有两个不同类型的栈...
  • a931136789
  • a931136789
  • 2015-11-23 20:47:37
  • 283

栈实现带括号的浮点型四则运算C++

/* Function:  带括号的四则运算表达式的求值(栈实现) Description:  利用栈这种数据结构来实现一个加减乘除以及带括弧的混合数学表达式的计算, 对于数学表达式的计算,...
  • guoyong10721073
  • guoyong10721073
  • 2012-09-20 15:00:58
  • 3080

四则运算(带括号)的小程序

看了数据结构与算法这本书,用刚学的栈写了一个能实现简单四则运算的小程序 主要是处理括号的问题 大概思路: 中缀表达式-》前缀表达式-》计算#include #include #include #...
  • amy260231120
  • amy260231120
  • 2016-03-09 21:03:27
  • 429

C语言实现表达式求值,支持+、-、*、/四则运算,并且支持多级括号,自定义了栈的操作。

#include #include #define N 50        //定义接收字符串大小 typedef struct _node_ {     int num_ch;     //...
  • niha1993825jian
  • niha1993825jian
  • 2014-10-30 12:59:54
  • 2782

栈的应用--递归与四则运算表达式求值

递归,是一个直接调用自己或通过一系列的调用语句间接的调用自己的函数。以斐波那契数列为例,对比其非递归和递归函数代码的区别,来让读者深刻了解递归的工作流程。四则运算表达式求值,是利用栈来完成四则运算,首...
  • dengpei187
  • dengpei187
  • 2016-07-11 09:57:14
  • 1072

栈的应用,实现简单的不带括号的四则运算

#include #include using namespace std; int f(const char* str, stack& s) { int i = 0; while(str[...
  • coder_yi_liu
  • coder_yi_liu
  • 2012-09-03 23:18:12
  • 853

栈的应用--四则运算表达式求值(java语言)

栈的应用–四则运算表达式求值(java语言)前言在复习数据结构的过程中,采用单链表实现了栈Stack,具体功能有如下几个功能:判断其是否为空栈、输出栈的长度、入栈、出栈并且实现Iterable借口,可...
  • njr465167967
  • njr465167967
  • 2016-07-20 16:11:05
  • 1855

[编程题]带括号的四则运算

一、问题描述输入字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。算术表达式的有效性由调用者保证; 输入描述:输入一个...
  • na_beginning
  • na_beginning
  • 2017-03-19 15:10:42
  • 1618
    个人资料
    持之以恒
    等级:
    访问量: 6515
    积分: 775
    排名: 6万+
    最新评论