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

数据结构与算法-栈与队列的应用递归表达式求值

参考学习:B站-逊哥带你学编程

栈与队列的应用

题1:

在这里插入图片描述

答案:B

题2:

在这里插入图片描述

答案:C

题3:

在这里插入图片描述

答案:D

题4:

在这里插入图片描述

答案:C

题5:

在这里插入图片描述

答案:B

题6:

在这里插入图片描述

答案: B

题7:

在这里插入图片描述

答案: C

题8:

在这里插入图片描述

答案:B

题9:

在这里插入图片描述

答案: C

题10:

在这里插入图片描述

答案:C

题11:

在这里插入图片描述

答案:B

题12:

在这里插入图片描述

答案:C

题13:

在这里插入图片描述

答案:D

题14:

在这里插入图片描述

答案:D

递归

非递归

在这里插入图片描述

int fun(int n) //非递归
{
    int sum = 0;
    for(int i=1; i<=n; i++)
    {
        sum += i;
    }
    return sum;
}

递归

在这里插入图片描述

//递归
int fun(int n)
{
    if(n == 1)
    {
        return 1;
    }
    else
    {
        return n + fun(n-1); //递归调用
    }
}

图示:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

最终返回的值为15。

斐波那契数列

在这里插入图片描述

非递归方式:
在这里插入图片描述

int fibonacci(int n) //非递归
{
    int last1 = 1;
    int last2 = 1;
    int result = 0;
    for(int i=3; i<=n; i++)
    {
        result = last1 + last2; //计算第i个斐波那契数
        last2 = last1; //更新last2
        last1 = result; //更新last1
    }
    return result; //返回第n个斐波那契数
}

递归方式:
在这里插入图片描述

int fibonacci(int n) //递归
{
    if(n == 1 || n == 2)
    {
        return 1;
    }
    else
    {
        return fibonacci(n-1) + fibonacci(n-2); //递归调用
    }
}

表达式求值

在这里插入图片描述

枚举

在这里插入图片描述

后缀表达式求值

题目:

82/2+56*-

求值过程图示:

先把需要运算的数字入栈,遇到运算符之后,再出栈,先入栈的为操作数op1,后入栈的为操作数op2,运算完成后,再次入栈,计算剩余项,直到字符串表达式结束。

在这里插入图片描述

代码实现:

使用栈实现:

//后缀表达式求值
#define MAXSIZE 100
typedef int ElemType;

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


typedef enum
{
    LEFT_PARE, RIGHT_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;
}

contentType getToken(char *symbol, int *index)
{
    *symbol = expr[*index]; //取出一个字符
    *index = *index + 1; //指针后移
    switch(*symbol)
    {
        case '(': return LEFT_PARE;
        case ')': return RIGHT_PARE;
        case '+': return ADD;
        case '-': return SUB;
        case '*': return MUL;
        case '/': return DIV;
        case '%': return MOD;
        case '\0': return EOS;
        default: return NUM;
    }
}

int eval(Stack *S)
{
    char symbol; //存放字符
    int op1, op2; //操作数
    int index = 0; //指针
    contentType token; //存放类型
    token = getToken(&symbol, &index); //取出一个字符
    ElemType result; //存放结果
    while(token != EOS) //不是结束符
    {
        if(token == NUM) //是数字
        {
            push(S, symbol-'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("result = %d\n", result); //输出结果
    return 1;
}

中缀表达式转后缀表达式

中缀表达式:x/(i-j)\*y →后缀表达式:xij-/y\* .

步骤:

1、如果是操作数,直接输出。

在这里插入图片描述

2、如果是运算符,判断优先级(优先级见下图),如果优先级大于栈顶元素的优先级,压入栈中。

在这里插入图片描述

3、当左括号在栈外时,属于最高优先级,当左括号在栈里时,属于最低优先级。

在这里插入图片描述

4、如果是操作数,直接输出。

在这里插入图片描述

5、如果是运算符,判断优先级(优先级见下图),如果优先级大于栈顶元素的优先级,压入栈中。

在这里插入图片描述

6、如果是操作数,直接输出。

在这里插入图片描述

7、如果是右括号,且栈顶元素不是左括号,持续出栈并输出,直到栈顶为左括号出栈结束最后将左括号也出栈。

(1)-符号出栈。

在这里插入图片描述

(2)出栈。

在这里插入图片描述

8、如果是运算符,判断优先级,如果优先级大于栈顶元素,压入栈中,否则将栈顶元素出栈输出,然后将当前运算符压入栈中。

(1)/出栈。

在这里插入图片描述

(2)*入栈。

在这里插入图片描述

9、如果是操作数,直接输出。

在这里插入图片描述

10、最后将栈中元素依次输出,完成转换。

在这里插入图片描述

运算符优先级

运算符优先级,数字越大,优先级越高。

在这里插入图片描述

代码实现:

#define MAXSIZE 100
typedef int ElemType;

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


typedef enum
{
    LEFT_PARE, RIGHT_PARE, 
    ADD, SUB, MUL, DIV, MOD, 
    EOS, NUM
} contentType;

char expr[] = "x/(i-j)*y"; //中缀表达式

> 这里是引用

Stack *initStack()
{
    Stack *S = (Stack *)malloc(sizeof(Stack));
    S->data = (ElemType *)malloc(sizeof(ElemType)*MAXSIZE);
    S->top = -1;
    return S;
}

contentType getToken(char *symbol, int *index)
{
    *symbol = expr[*index]; //取出一个字符
    *index = *index + 1; //指针后移
    switch(*symbol)
    {
        case '(': return LEFT_PARE;
        case ')': return RIGHT_PARE;
        case '+': return ADD;
        case '-': return SUB;
        case '*': return MUL;
        case '/': return DIV;
        case '%': return MOD;
        case '\0': return EOS;
        default: return NUM;
    }
}

int print_token(contentType token)
{
    switch(token)
    {
        case LEFT_PARE: printf("("); break;
        case RIGHT_PARE: printf(")"); break;
        case ADD: printf("+"); break;
        case SUB: printf("-"); break;
        case MUL: printf("*"); break;
        case DIV: printf("/"); break;
        case MOD: printf("%"); break;
        case EOS: printf("\n"); break;
        default: break;
    }
    return 1;
}


void postfix(Stack *S)
{
    int in_stack[] = {0, 19, 12, 12, 13, 13, 13, 0}; //栈内优先级
    int out_stack[] = {20, 19, 12, 12, 13, 13, 13, 0}; //栈外优先级
    contentType token; //存放类型
    int index = 0; //指针
    S->data[0] = EOS; //栈底放结束符
    char symbol; //存放字符
    ElemType e; //存放栈顶元素

    token  = getToken(&symbol, &index); //取出一个字符

    while(token != EOS) //不是结束符
    {
        if(token == NUM) //是数字
        {
            printf("%c", symbol); //输出
        }
        else if(token == RIGHT_PARE) //是右括号
        {
            while(getTop(S, &e) && e != LEFT_PARE) //取出栈顶元素
            {
                pop(S, &e); //出栈
                print_token(e); //输出
            }
            pop(S, &e); //出栈
        }
        else //是运算符
        {
            while(in_stack[S->data[S->top]] >= out_stack[token]) //取出栈顶元素
            {
                pop(S, &e); //出栈
                print_token(e); //输出
            }
            push(S, token); //入栈
        }
        token = getToken(&symbol, &index); //继续取出一个字符
    }

}

相关文章:

  • 当扩展屏显示【输入不支持】怎么解决?!
  • 当Ollama遇上划词翻译:我的Windows本地AI服务搭建日记
  • 一些常用的Yum源
  • 项目版本号生成
  • 嵌入式玩具--无人机字幕
  • 【C++】32.C++11​(4)
  • 了解module_driver宏
  • Flask中获取请求参数的一些方式总结
  • 什么是GraphQL?
  • Day45(补)【软考】2022年下半年软考软件设计师综合知识真题-计算机软件知识1
  • 电子制造企业数字化转型实战:基于Odoo构建MES平台的深度解决方案
  • DC-7靶机渗透测试全过程
  • 学习数据结构(10)栈和队列下+二叉树(堆)上
  • 机器学习实战(2):数据预处理——机器学习的第一步
  • C++效率掌握之STL库:string底层剖析
  • Zotero7 从下载到安装
  • K-均值(K-means)
  • LM Studio笔记
  • 使用 Vite + React 19 集成 Tailwind CSS 与 shadcn/ui 组件库完整指南
  • 日常知识点之遗留问题梳理(被问到用uml画设计模式)
  • 时隔3年俄乌直接谈判今日有望重启:谁参加,谈什么
  • 哪种“网红减肥法”比较靠谱?医学专家和运动专家共同解答
  • “异常”只停留在医院里,用艺术为“泡泡宝贝”加油
  • “一码难求”的Manus开放注册但价格不菲,智能体距离“实用”还有多远
  • 【社论】个人破产探索,要守住“诚实而不幸”的底线
  • 受贿3501万余元,中石油原董事长王宜林一审被判13年