首页 > 编程语言 >栈实现算术优先级运算c++

栈实现算术优先级运算c++

时间:2023-10-20 20:12:51浏览次数:26  
标签:case return 算术 top c++ char int base 优先级

#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;

#define STACK_INIT_SIZE 100   //栈初始开辟空间大小
#define STACK_INCREMENT 10    //栈追加空间大小

//优先级数组,2表示top>c,1表示top<c,0表示top=c,-1表示错误
int prior[7][7] = { {2,2,1,1,1,2,2},{2,2,1,1,1,2,2},{2,2,2,2,1,2,2},
{2,2,2,2,1,2,2},{1,1,1,1,1,0,-1},{2,2,2,2,-1,2,2},{1,1,1,1,1,-1,0} };

//******************************************************************
//                           整形栈的实现
//******************************************************************

//整形栈结构体
typedef struct {
    int* base;
    int* top;
    int size;
}intStack;


//栈初始化
intStack intStack_init()
{
    intStack s;
    s.base = (int*)malloc(sizeof(int) * STACK_INIT_SIZE);
    s.top = s.base;
    s.size = STACK_INIT_SIZE;
    return s;
}

//入栈
void intPush(intStack* s, int e)
{
    if (s->top - s->base >= s->size)
    {
        s->size += STACK_INCREMENT;
        s->base = (int*)realloc(s->base, sizeof(int) * s->size);
    }
    *s->top = e;
    s->top++;
}

//出栈
int intPop(intStack* s)
{
    if (s->top != s->base)
    {
        s->top--;
        return *s->top;
    }
    return -1;
}


//******************************************************************
//                         字符栈的实现
//******************************************************************

//字符栈结构体
typedef struct {
    char* base;
    char* top;
    int size;
}charStack;


//栈初始化
charStack charStack_init()
{
    charStack s;
    s.base = (char*)malloc(sizeof(char) * STACK_INIT_SIZE);
    s.top = s.base;
    s.size = STACK_INIT_SIZE;
    return s;
}

//入栈
void charPush(charStack* s, char e)
{
    if (s->top - s->base >= s->size)
    {
        s->size += STACK_INCREMENT;
        s->base = (char*)realloc(s->base, sizeof(char) * s->size);
    }
    *s->top = e;
    s->top++;
}

//出栈
char charPop(charStack* s)
{
    if (s->top != s->base)
    {
        s->top--;
        return *s->top;
    }
    return -1;
}

//得到栈顶元素,但不出栈
char getTop(charStack* s)
{
    s->top--;
    char temp = *s->top;
    s->top++;
    return temp;
}

//******************************************************************
//                      使用栈结构求解表达式
//******************************************************************

//得到操作符在数组prior中的索引值
int getIndex(char ope)
{
    switch (ope)
    {
    case '+': return 0;
    case '-': return 1;
    case '*': return 2;
    case '/': return 3;
    case '(': return 4;
    case ')': return 5;
    case '#': return 6;
    }
}

//求得两个操作数和一个操作符的运算结果
int compute(int operand1, int operand2, char ope)
{
    switch (ope)
    {
    case '+': return operand1 + operand2;
    case '-': return operand1 - operand2;
    case '*': return operand1 * operand2;
    case '/': return operand1 / operand2;
    }
}

//由表达式字符串指针,得到下一个操作符或操作数
//得到操作符标记key=0,得到操作数标记key=1
//返回偏移后的字符串指针
char* operand_or_operator(char* p, int* operand, char* ope, int* key)
{
    while (*p == ' ') p++;               //跳过空格
    if (*p >= '0' && *p <= '9')          //得到操作数
    {
        *operand = 0;
        int dec = 1;                    //十进制数位权重
        intStack s = intStack_init();   //使用整形栈转化数值        
        while (*p >= '0' && *p <= '9')   //操作数位由高到低依次压入栈中
        {
            intPush(&s, *p - '0');
            p++;
        }
        while (s.base != s.top)          //依次读取栈中操作数各位
        {
            *operand += intPop(&s) * dec;
            dec *= 10;
        }
        *key = 1;
    }
    else                               //得到操作符
    {
        switch (*p)
        {
        case '+':*ope = '+'; break;
        case '-':*ope = '-'; break;
        case '*':*ope = '*'; break;
        case '/':*ope = '/'; break;
        case '(':*ope = '('; break;
        case ')':*ope = ')'; break;
        case '#':*ope = '#'; break;
        }
        p++;
        *key = 0;
    }
    return p;
}

//由表达式字符串得到最终计算结果
int output(char* p)
{
    intStack operandStack = intStack_init();     //初始化操作数栈
    charStack operatorStack = charStack_init();  //初始化操作符栈
    charPush(&operatorStack, '#');
    int operand, key, index1, index2;
    char ope;
    while (operatorStack.base != operatorStack.top)  //操作符栈空代表计算结束
    {
        p = operand_or_operator(p, &operand, &ope, &key);
        if (key)  //得到操作数
            intPush(&operandStack, operand);
        else     //得到操作符
        {
            index1 = getIndex(getTop(&operatorStack));
            index2 = getIndex(ope);
            while (prior[index1][index2] == 2)   //top优先级高于c
            {
                intPush(&operandStack, compute(intPop(&operandStack), intPop(&operandStack), charPop(&operatorStack)));
                index1 = getIndex(getTop(&operatorStack));
            }
            if (prior[index1][index2] == 1)      //top优先级低于c
            {
                charPush(&operatorStack, ope);
            }
            else if (prior[index1][index2] == 0) //top优先级等于c
            {
                charPop(&operatorStack);
            }
            else
            {
                printf("Enter Error!!!\n");
                return 0XFFFFFFFF;
            }
        }
    }
    return intPop(&operandStack);
}

//******************************************************************
//                              主函数
//******************************************************************

void main()
{
    char str[100];
    int out;
    printf("以#结尾:\n");
    cin>> str;
    out = output(str);
    if (out != 0XFFFFFFFF)
        printf("结果等于:\n%d\n\n", out);
}

 

标签:case,return,算术,top,c++,char,int,base,优先级
From: https://www.cnblogs.com/saucerdish/p/17777920.html

相关文章

  • C++ Primer 中文版(第 5 版)pdf电子版 C++ Primer, 5th Edition
    C++Primer中文版(第5版)pdf电子版C++Primer,5thEdition作者:[美]StanleyB.Lippman/[美]JoséeLajoie/[美]BarbaraE.Moo原作名:C++Primer,5thEdition......
  • C++类型转换
    C++类型转换1.const_castconst_cast可以将const转换成非const,也可以将非const转换成const。需要注意的是const_cast只能用于改变指针或者引用的底层const。底层const和顶层const首先要弄清楚const修饰的到底是谁,用顶层表示指针本身是个常量(指针常量),底层表示指针所指向的对......
  • error: Microsoft Visual C++ 14.0 is required. Get it with "Build Tools for Visua
    error:MicrosoftVisualC++14.0isrequired.Getitwith"BuildToolsforVisualStudio":https://visualstudio.microsoft.com/downloads/ 一、背景说明在编译安装达梦数据库的Python驱动dmPython时,执行编译安装命令如下:pythonsetup.pyinstall 报错信息......
  • 安装编译工具 Microsoft Visual C++ Build Tools
    安装编译工具MicrosoftVisualC++BuildTools 一、下载VS2019下载地址如下:https://gitee.com/ivy258/vc2019-code-2022/tree/master/bag  或者从如下百度网盘中下载: 二、安装VS2019 ......
  • c++ 基本语法_1
    //1.主函数里面的各个含义意思#include<iostream>              #include表示预处理,引入一个iostream的库。<>里面表示的是一个头文件,每一个都有其功能intmain()                      #main表......
  • C++基本语法:
    C++基本语法:C++程序可以定义为对象的集合,这些对象通过调用彼此的方法进行交互。对象:对象具有状态和行为。例如:一只猫的状态(颜色、名称、品种、行为、摇动、叫唤、吃),对象是类的实例。类:类可以定义为描述对象行为(或者状态)的模版(或者蓝图)。方法:从基本上说,一个方法表示一种行为。......
  • 3——of C++枚举
    C++枚举类型总结一下C++里面的枚举类就是为了方便字符表示数据的一种方式吧,java枚举类也差不多默认情况下,一个枚举变量没赋值的话则编译器赋为0,后面一次加1枚举类型默认为int类型,也可以赋值其他数字类型枚举的取值范围就不太纠结,感觉没啥用;枚举和switch配合,很棒enumexampl......
  • 目录:C++primer plus
    1:链接2:链接3:链接4:链接5:链接6:链接7:链接8:链接9:链接0:链接1:链接2:链接3:链接4:链接5:链接6:链接7:链接8:链接9:链接0:链接1:链接2:链接3:链接4:链接5:链接6:链接7:链接8:链接9:链接0:链接1:链接2:链接3:链接4:链接5:链接6:链接7:链接8:链接9:链接0:链接1:链接2:链接3:链接4......
  • C++ 中的 for 循环条件拆解
    引子CSP-J真题中,for循环后面括号内的几个表达式组形式特别……for循环的格式for(表达式一;表达式二;表达式三){循环体;}示例代码:循环输出1-100for(inti=1;i<=100;i++){cout<<i<<"";}for循环的执行顺序①表达式一(只执行一次)②表达式二③循环体④表......
  • C++零基础教程(函数重载)
    (文章目录)前言本篇文章来讲解函数重载,函数重载在C++中是非常重要的一个概念。一、概念讲解C++中的函数重载是指在同一个作用域中定义多个具有相同名称但参数列表不同的函数。函数重载允许使用相同的函数名来表示执行类似但具有不同参数类型或参数数量的操作。这样做可以提高......