zoukankan      html  css  js  c++  java
  • 链栈的基本操作 三(中缀表达式 完整版)

    #include<stdio.h>
    #include<malloc.h>
    #include<string.h>
    #define ElemType char
    #define MAXSIZE 100
    typedef struct OptrStack{//定义运算符链栈
    char otr;
    struct OptrStack *next;
    }OPtrStack;

    typedef struct OPndStack{
    int opnd;
    struct OPndStack *next;
    }OPndStack;

    OPtrStack *Init_optr(OPtrStack *top){//初始化一个带有头结点的运算符链栈
    top=(OPtrStack *)malloc(sizeof(OPtrStack));
    top->next=NULL;
    return top;
    }

    OPndStack *Init_opnd(OPndStack *top){//初始化一个带有头结点的操作数链栈
    top=(OPndStack *)malloc(sizeof(OPndStack));
    top->next=NULL;
    return top;
    }
    OPtrStack *Push_optr(OPtrStack *top,char e){//运算符入栈操作
    OPtrStack *p;
    p=(OPtrStack *)malloc(sizeof(OPtrStack));
    if(!p){
    printf("栈满");
    }
    else{
    p->otr=e;
    p->next=top->next;
    top->next=p;
    }
    return top;
    }

    OPndStack *Push_opnd(OPndStack *top,int e){//入栈操作
    OPndStack *p;
    p=(OPndStack *)malloc(sizeof(OPndStack));
    if(!p){
    printf("栈满");
    }
    else{
    p->opnd=e;
    p->next=top->next;
    top->next=p;
    }
    return top;
    }
    char Pop_optr(OPtrStack *top){
    OPtrStack *p;
    char e;
    p=top->next;
    if(p==NULL){
    printf("栈空");
    }
    else{
    e=p->otr;
    top->next=p->next;
    free(p);
    }
    return e;
    }

    int Pop_opnd(OPndStack *top){
    OPndStack *p;
    int e;
    p=top->next;
    if(p==NULL){
    printf("栈空");
    }
    else{
    e=p->opnd;
    top->next=p->next;
    free(p);
    }
    return e;
    }
    char Get_optr(OPtrStack *optr){
    char otr;
    OPtrStack *p;
    p=optr->next;
    if(p==NULL){
    printf("栈已空");
    }
    else{
    otr=p->otr;
    }
    return otr;
    }
    int Get_opnd(OPndStack *opnd){
    int ond;
    OPndStack *p;
    p=opnd->next;
    if(p==NULL){
    printf("栈已空");
    }
    else{
    ond=p->opnd;
    }
    return ond;
    }
    int OpId(char op){
    switch(op){
    case '+':return 0;
    case '-':return 1;
    case '*':return 2;
    case '/':return 3;
    case '(':return 4;
    case ')':return 5;
    case '#':return 6;
    }
    }
    char Precede(int otrID,int exID){//此处为栈内与栈外运算符的优先级比较
    char precede[7][7]={{'>','>','<','<','<','>','>'},//+
    {'>','>','<','<','<','>','>'},//-
    {'>','>','>','>','<','>','>'},//*
    {'>','>','>','>','<','>','>'},///
    {'<','<','<','<','<','=',' '},//(
    {'>','>','>','>',' ','>','>'},//)
    {'<','<','<','<','<',' ','='}};//#
    return precede[otrID][exID];
    }
    int OPnd(char ex){
    if(ex>='0' && ex<='9'){
    return 1;
    }
    else{
    return 0;
    }
    }
    int Opration(int ond2,char pre_op,int ond1){
    int ond3;
    switch(pre_op){
    case '+' :
    ond3=ond2+ond1;return ond3;
    case '-' :
    ond3=ond2-ond1;return ond3;
    case '*' :
    ond3=ond2*ond1;return ond3;
    case '/' :
    ond3=ond2/ond1;return ond3;
    }
    }
    void MidExpression_Eval(char *ex,OPtrStack *optr,OPndStack *opnd){//中缀表达式函数
    //OPtrStack *optr;//定义一个运算符链栈指针
    //OPndStack *opnd;//定义一个运算数链栈指针
    char otr,pre_op,test;//otr定义一个栈内运算符
    int ond1,ond2,ond3,opnd4;//ond1,ond2,ond3分别是定义的从栈内依次取出的第一个运算数和第二个运算数
    optr=Init_optr(optr);
    opnd=Init_opnd(opnd);
    optr=Push_optr(optr,'#');
    otr=Get_optr(optr);
    while(*ex!='#'||Get_optr(optr)!='#'){
    if(OPnd(*ex)==1){//如果输入的从表达式读入的字符为数字,则将其压入到运算数栈
    opnd=Push_opnd(opnd,*ex-'0');
    ex++;
    }else{
    otr=Get_optr(optr);

    if(Precede(OpId(otr),OpId(*ex))=='<'){//如果栈内运算符的优先级小于栈外的,则压如操作符栈
    optr=Push_optr(optr,*ex);
    ex++;
    }else if(Precede(OpId(otr),OpId(*ex))=='='){//如果栈内栈外操作符优先级相等,则将其出栈,消去
    Pop_optr(optr);
    ex++;
    }
    else if(Precede(OpId(otr),OpId(*ex))=='>'){//如果栈内操作符较大,则出栈进行运算
    otr=Pop_optr(optr);
    if(otr=='#')
    break;
    ond1=Pop_opnd(opnd);//从运算数栈内取出第一个操作数
    ond2=Pop_opnd(opnd);//从运算数栈内取出第二个操作数
    ond3=Opration(ond2,otr,ond1);//进行运算
    Push_opnd(opnd,ond3);将运算后的操作数入栈
    }
    }
    }
    printf("%d",Get_opnd(opnd));

    }
    int main(){
    OPtrStack *OPTR;//初始化一个运算数栈,一个运算符栈
    OPndStack *OPND;//初始化一个运算数栈,
    char express[MAXSIZE];//输入一个中缀表达式
    char *ex;//定义一个指针,指向表达式第一个字符的地址
    printf("输入中缀表达式: ");
    gets(express);
    ex=express;
    MidExpression_Eval(ex,OPTR,OPND);
    return 0;
    }

  • 相关阅读:
    修改JavaScript脚本并离线编译后将数据同步到Web和Web app
    修改JavaScript脚本并离线编译后将数据同步到Web和Web app
    基于JavaScript离线编译工具环境搭建
    基于JavaScript离线编译工具环境搭建
    超赞!聊聊WEB APP、HYBRID APP与NATIVE APP的设计差异
    超赞!聊聊WEB APP、HYBRID APP与NATIVE APP的设计差异
    基于JavaScript的安卓Web App测试环境搭建
    运行cmake,报package 'minigui' not found
    提示找不到include/common.h 提示No package 'minigui' found
    error: 'va_list' from type 'struct __va_list_tag *'
  • 原文地址:https://www.cnblogs.com/jiafeng1996/p/11324792.html
Copyright © 2011-2022 走看看