当前位置: 首页 > article >正文

表达式求值(后缀表达式)

后缀表达式

后缀表达式是给计算机去看的,一个个压进栈中; 遇到操作符就计算再将计算出的结果压到栈中;最后弹出结果。

1.栈的初始化(动态存储)

typedef struct {
    ElemType* data;
    int top;
}Stack;
//初始化
Stack* initStack()
{
    Stack* s = (Stack*)malloc(sizeof(Stack));
    s->data = (ElemType*)malloc(sizeof(ElemType) * MAXSIZE);
    s->top = -1;
    return s;
}

2.用了一个枚举类型去存储一些操作

typedef enum
{   //左右括号  
    LEFT_PARE, RIGTH_PARE,
    ADD,SUB,MUL,DIV,MOD,
    EOS,NUM 
}contentType;

3.对栈的入栈和出栈操作

// 入栈操作
int push(Stack* s, ElemType elem) {
    if (s->top == MAXSIZE - 1) {
        printf("栈满,无法入栈\n");
        return 0;
    }
    s->top++;
    s->data[s->top] = elem;
    return 1;
}
int pop(Stack* s, ElemType* elem) {
    if (s->top == -1) {
        printf("栈空,无法出栈\n");
        return 0;
    }
    *elem = s->data[s->top];
    s->top--;
    return 1;
}

4.对操作数的具体操作

  • 我们来模拟当index = 0时 在 字符数组中下标为0的字符是8 然后可以得到 symbol = '8'

  • 进入switch中可以返回NUM

  • 在eval函数中,token为NUM就识别为数字,就压栈

  • 不断的循环最后完成表达式求值

contentType getToken(char* symbol, int* index)
{
    *symbol = expr[*index]; //先将0的地址传过来现在值为8
    *index = *index + 1; //index变2
    switch (*symbol)//将8存进去
    {
    case'(':
        return LEFT_PARE;
    case')':
        return RIGTH_PARE;
    case'+':
        return ADD;
    case'-':
        return SUB;
    case'*':
        return MUL;
    case'/':
        return DIV;
    case'%':
        return MOD;
    case'\0':
        return EOS;
    default:
        return NUM;  //数字8 返回NUM
    }
}
​
int eval(Stack* s)
{
    char symbol;
    int op1, op2;
    int index = 0;
    contentType token; //字符的类型
    token = getToken(&symbol, &index);//识别到是哪个字符,返回什么算法
    ElemType result;
    while (token != EOS) {//一直循环到字符数组的\0结束
        if (token == NUM)//如果是数字就压栈
        {
            push(s, symbol - '0');// 字符减去'0' 是数值
        }
        else
        {
            pop(s, &op2); //如果是操作符就弹出进行计算
            pop(s, &op1);
​
            switch (token)
            {
            case ADD:
                push(s, op1 + op2);
                break;
            case SUB:
                push(s, op1 - op2);
                break;
            case MUL:
                push(s, op1 * op2);
                break;
            case DIV:
                push(s, op1 / op2);
                break;
            case MOD:
                push(s, op1 % op2);
                break;
            default:
                break;
            }
        }
        token = getToken(&symbol, &index);
​
    }
    pop(s, &result);
    printf("%d\n", result);
    return 1;
}

5.一个全局变量,字符数组

char expr[] = "82/2+56*-";

完整代码如下

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
typedef int ElemType;

typedef struct {
	ElemType* data;
	int top;
}Stack;

typedef enum
{	//左右括号	
	LEFT_PARE, RIGTH_PARE,
	ADD,SUB,MUL,DIV,MOD,
	EOS,NUM 
}contentType;

char expr[] = "82/2+56*-";

//初始化
Stack* initStack()
{
	Stack* s = (Stack*)malloc(sizeof(Stack));
	s->data = (ElemType*)malloc(sizeof(ElemType) * MAXSIZE);
	s->top = -1;
	return s;
}

// 入栈操作
int push(Stack* s, ElemType elem) {
	if (s->top == MAXSIZE - 1) {
		printf("栈满,无法入栈\n");
		return 0;
	}
	s->top++;
	s->data[s->top] = elem;
	return 1;
}
int pop(Stack* s, ElemType* elem) {
	if (s->top == -1) {
		printf("栈空,无法出栈\n");
		return 0;
	}
	*elem = s->data[s->top];
	s->top--;
	return 1;
}
contentType getToken(char* symbol, int* index)
{
	*symbol = expr[*index]; //先将0的地址传过来现在值为8
	*index = *index + 1; //index变2
	switch (*symbol)//将8存进去
	{
	case'(':
		return LEFT_PARE;
	case')':
		return RIGTH_PARE;
	case'+':
		return ADD;
	case'-':
		return SUB;
	case'*':
		return MUL;
	case'/':
		return DIV;
	case'%':
		return MOD;
	case'\0':
		return EOS;
	default:
		return NUM;  //数字8 返回NUM
	}
}

int eval(Stack* s)
{
	char symbol;
	int op1, op2;
	int index = 0;
	contentType token; //字符的类型
	token = getToken(&symbol, &index);//识别到是哪个字符,返回什么算法
	ElemType result;
	while (token != EOS) {//一直循环到字符数组的\0结束
		if (token == NUM)//如果是数字就压栈
		{
			push(s, symbol - '0');// 字符减去'0' 是数值
		}
		else
		{
			pop(s, &op2); //如果是操作符就弹出进行计算
			pop(s, &op1);

			switch (token)
			{
			case ADD:
				push(s, op1 + op2);
				break;
			case SUB:
				push(s, op1 - op2);
				break;
			case MUL:
				push(s, op1 * op2);
				break;
			case DIV:
				push(s, op1 / op2);
				break;
			case MOD:
				push(s, op1 % op2);
				break;
			default:
				break;
			}
		}
		token = getToken(&symbol, &index);

	}
	pop(s, &result);
	printf("%d\n", result);
	return 1;
}
int main()
{
	Stack* s = initStack();
	eval(s);
}


http://www.kler.cn/a/571713.html

相关文章:

  • 现在创业的风口有哪些?
  • Flink学习方法
  • 土木工作2年,考研到211计科,目前研二,该如何准备秋招?
  • Linux中使用cpulimit 限制 cpu 占用率
  • FastGPT 引申:如何基于 LLM 判断知识库的好坏
  • DeepSeek赋能Power BI:开启智能化数据分析新时代
  • CSS层叠上下文解析与应用
  • 【大模型系列篇】国产开源大模型DeepSeek-V3技术报告解析
  • 第十五届蓝桥杯:dfs之数字接龙
  • 基于Flask的造价信息可视化分析系统
  • 盘古信息携手艾罗能源启动IMS数字化智能制造工厂项目,共筑新能源行业数字化标杆
  • C++17 新增特性总结: 核心语言特性
  • C#:LINQ学习笔记01:LINQ基础概念
  • 力扣1594. 矩阵的最大非负积
  • 爬蟲動態IP代理與數據採集穩定性
  • 【文生图】Win10环境借助基于ComfyUI的图狗2.3.1抢先体验阿里万相wan2.1
  • 【Linux】【网络】UDP打洞-->不同子网下的客户端和服务器通信(未成功版)
  • OpenHarmony文件管理子系统
  • XMOS推出“免开发固件方案”将数字接口音频应用的开发门槛大幅降低
  • angular实现nodejs增删改查