王道计算机考研 数据结构C语言复现-第七章-表达式(波兰式)

这篇文章收录了王道考研课程中涉及的数据结构的所有代码。此外,本博客可能会添加一些额外的代码(不仅限于王道考研),因为408考试中会频繁考察一些冷门的知识点,所以这篇博客会涵盖所有相关的代码。这也是我数据结构的第一轮复习,希望能与大家共同进步。由于博客篇幅的限制,可能无法一次性包含所有内容,欢迎指出代码错误部分!!!

你想要的都在下面!!!

// @FileName  :07BiaoDaShi.c
// @Time      :2023/8/15 14:57
// @Author    :YKW
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>

#define MaxSize 50
//表达式求值(波兰式/逆波兰式,前缀/后缀表达式)
//后缀表达式 5 7 1 1 + - / 3 * 2 1 1 + + -
//A B + C D * E / - F +
typedef struct Calc {//计算结构体
    char num[MaxSize];
    int top;
} calc;
typedef struct Revert{//转换结构体
    char data;
    struct revert*next;
}revert;

void cInitStack(calc *C) {
    C->top = -1;
}
bool cPop(calc *C, char *e) {
    *e = C->num[C->top];
    (C->top)--;
}
bool cPush(calc *C, char e) {
    C->num[++(C->top)] = e;
}

void rInitStack(revert *S) {
    S->next=NULL; //刚开始没有结点
}
bool StackEmpty(revert* S){
    return S->next==NULL;
}
bool rPop(revert *S, char *e) {
    if(S->next==NULL)//空栈
        return false;
    *e=S->data;
    revert *p=S;
    S=S->next;
    free(p);
    return true;
}
bool rPush(revert *S, char e) {
    revert *s=(revert*)malloc(sizeof(revert));
    if(s==NULL)//内存不足,分配失败
        return false;
    s->data=e;
    s->next=S;
    S=s;
    return true;
}

//计算逆波兰(后缀)
int CRP() {
    calc C;
    cInitStack(&C);
    char s;
    char ans = 0;
    char num1, num2;
    printf("输入后缀表达式:");
    //scanf( "%[^\n]",str); %[^\n] 的意思就是“遇到换行才结束”
    while (scanf("%c", &s) != EOF) {
        if (isdigit(s) && s != 0) {//扫到符号开始算,算到没有符号
            cPush(&C, s);
        } else if (s == '+' || s == '-' || s == '*' || s == '/') {
            cPop(&C, &num1);
            cPop(&C, &num2);
            int n1=num1-'0',n2=num2-'0';
            if (s == '+')
                ans = n2 + n1;
            else if (s == '-')
                ans = n2 - n1;
            else if (s == '*')
                ans = n2 * n1;
            else if (s == '/')
                ans = n2 / n1;
            cPush(&C, ans+'0');
        }else if(s=='\n'){
            return C.num[C.top]-'0';
        }
    }
}
//转化为中缀
char RRP() {
    char temp,a[MaxSize],b[MaxSize]; //静态数组a、b分别存放要转换的中缀表达式和转换后的后缀表达式,字符变量temp存放弹出的栈顶元素
    scanf("%s",&a); //需要您输入中缀表达式
    revert *S;//初始化一个栈,用于保存括号和暂时还不能确定运算顺序的运算符
    rInitStack(S); //初始化链栈
    int i,j,length=strlen(a); //length为输入的中缀表达式的总长度,i、j分别为静态数组a、b的索引下标
    for(i=j=0;i<length;i++){
        if(a[i]>='0' && a[i]<='9'){ //若当前字符是数字,字符0-9的ACSII码范围是[48,57]
            b[j++]=a[i];
            if(a[i+1]=='+'||a[i+1]=='-'||a[i+1]=='*'||a[i+1]=='/') //若下一个字符是运算符,即+、-、*、/,则b加一个空格,以免不同的操作数混在一起
                b[j++]=' ';
        }
        else if(a[i]=='(')
            rPush(S,a[i]); //若当前字符是左括号则直接入栈
        else if(a[i]==')'){ //若当前字符是右括号
            while(StackEmpty(S)==0){ //栈非空则不断弹出栈内字符并加入后缀表达式
                rPop(S,&temp);
                if(temp=='(') //直到弹出左括号停止,注意这个(不加入后缀表达式
                    break;
                b[j++]=temp;
                b[j++]=' '; //加一个空格,从而将字符隔开
            }
        }
        else switch(a[i]){ //若当前字符是运算符
                case '*': case '/':{
                    while(StackEmpty(S)==0){ //若栈非空,则弹出栈中优先级高于或等于当前运算符的所有运算符,并将这些运算符加入后缀表达式
                        rPop(S,&temp);
                        if(temp=='/'||temp=='*'){
                            b[j++]=temp;
                            b[j++]=' '; //加一个空格,从而将字符隔开
                        }
                        else if(temp=='('||temp=='-'||temp=='+'){//若栈顶元素是左括号或者是优先级低于当前字符的运算符,则将栈顶元素入栈
                            rPush(S,temp);
                            break;
                        }
                    }
                    rPush(S,a[i]); //把当前字符入栈
                    break;
                }
                case '-': case '+':{
                    while(StackEmpty(S)==0){ //若栈非空,则弹出栈中优先级高于或等于当前运算符的所有运算符,并将这些运算符加入后缀表达式
                        rPop(S,&temp);
                        if(temp=='('){//若栈顶元素是左括号,则将栈顶元素入栈
                            rPush(S,temp);
                            break;
                        }
                        else if(temp=='/'||temp=='*'||temp=='-'||temp=='+'){
                            b[j++]=temp;
                            b[j++]=' '; //加一个空格,从而将字符隔开
                        }
                    }
                    rPush(S,a[i]); //把当前字符入栈
                    break;
                }
            }
    }
    while(StackEmpty(S)==0){ //栈非空时依次弹出栈顶元素并加入后缀表达式
        rPop(S,&temp);
        b[j++]=temp;
        b[j++]=' '; //加一个空格,从而将字符隔开
    }
    printf("结果是:\n");
    for(i=0;i<j;i++) //j是数组中下一个可以插入元素的位置下标,因此b中存放字符的索引区间为[0,j-1]
        printf("%c",b[i]); //输出b中的元素
    printf("\n");
    return 0;
}
int main() {
//    printf("%d", CRP());
    RRP();
}

  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值