C语言中栈和队列实现表达式求值的实例

C语言中栈和队列实现表达式求值的实例

在 C 语言中,可以利用栈和队列来实现表达式求值。表达式求值是将字符串形式的表达式转换成计算结果的过程,包括算数表达式和逻辑表达式两种类型。下面将分别对这两种表达式求值进行实例说明。

算数表达式求值

算数表达式求值的过程包括词法分析、语法分析和计算三个过程。词法分析是将字符串表达式拆分成由数字、运算符和括号等组成的多个 Token,语法分析是按照优先级和括号顺序逐步计算拆分后的 Token,计算是最终得到计算结果的过程。

以下是一个简单的算数表达式求值的例子:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAX_EXPR_SIZE 100

typedef struct {
    char expr[MAX_EXPR_SIZE];
    int len;
} Expr;

typedef struct {
    int num;
    char op;
} Token;

typedef struct {
    int num[MAX_EXPR_SIZE];
    int top;
} Stack;

int op_priority(char op) {
    switch (op) {
        case '+':
        case '-':
            return 1;
        case '*':
        case '/':
            return 2;
        default:
            return 0;
    }
}

void push(Stack *stack, int num) {
    stack->top++;
    stack->num[stack->top] = num;
}

int pop(Stack *stack) {
    int num = stack->num[stack->top];
    stack->top--;
    return num;
}

int calculate(Token token, int num1, int num2) {
    switch (token.op) {
        case '+':
            return num1 + num2;
        case '-':
            return num1 - num2;
        case '*':
            return num1 * num2;
        case '/':
            return num1 / num2;
        default:
            return 0;
    }
}

int eval(Expr expr) {
    Stack num_stack;
    num_stack.top = -1;
    int num1, num2;
    char op;
    Token token;
    for (int i = 0; i < expr.len; i++) {
        if (isdigit(expr.expr[i])) {
            int num = expr.expr[i] - '0';
            i++;
            while (i < expr.len && isdigit(expr.expr[i])) {
                num = num * 10 + expr.expr[i] - '0';
                i++;
            }
            push(&num_stack, num);
            i--;
        } else if (expr.expr[i] == ')') {
            num2 = pop(&num_stack);
            op = pop(&num_stack);
            num1 = pop(&num_stack);
            push(&num_stack, calculate((Token){op}, num1, num2));
        } else if (expr.expr[i] == '+' || expr.expr[i] == '-' || expr.expr[i] == '*' || expr.expr[i] == '/') {
            while (num_stack.top >= 0 && op_priority(num_stack.num[num_stack.top]) >= op_priority(expr.expr[i])) {
                num2 = pop(&num_stack);
                op = pop(&num_stack);
                num1 = pop(&num_stack);
                push(&num_stack, calculate((Token){op}, num1, num2));
            }
            push(&num_stack, expr.expr[i]);
        } else if (expr.expr[i] == '(') {
            push(&num_stack, expr.expr[i]);
        }
    }
    while (num_stack.top >= 0) {
        num2 = pop(&num_stack);
        op = pop(&num_stack);
        num1 = pop(&num_stack);
        push(&num_stack, calculate((Token){op}, num1, num2));
    }
    return pop(&num_stack);
}

int main() {
    Expr expr = {"(5+1)*6/2-3"};
    expr.len = strlen(expr.expr);
    printf("Result: %d\n", eval(expr));
    return 0;
}

逻辑表达式求值

逻辑表达式求值的过程相对比较简单,只需要根据布尔运算的规则逐个计算即可。逻辑表达式求值的结果只有 true 或 false 两种。

以下是一个简单的逻辑表达式求值的例子:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAX_EXPR_SIZE 100

typedef struct {
    char expr[MAX_EXPR_SIZE];
    int len;
} Expr;

typedef struct {
    char op;
} Token;

typedef struct {
    int value[MAX_EXPR_SIZE];
    int top;
} Stack;

void push(Stack *stack, int value) {
    stack->top++;
    stack->value[stack->top] = value;
}

int pop(Stack *stack) {
    int num = stack->value[stack->top];
    stack->top--;
    return num;
}

int eval(Expr expr) {
    Stack value_stack;
    value_stack.top = -1;
    int value1, value2;
    char op;
    Token token;
    for (int i = 0; i < expr.len; i++) {
        if (expr.expr[i] == 't') {
            push(&value_stack, 1);
        } else if (expr.expr[i] == 'f') {
            push(&value_stack, 0);
        } else if (expr.expr[i] == '|') {
            value2 = pop(&value_stack);
            value1 = pop(&value_stack);
            push(&value_stack, value1 || value2);
        } else if (expr.expr[i] == '&') {
            value2 = pop(&value_stack);
            value1 = pop(&value_stack);
            push(&value_stack, value1 && value2);
        } else if (expr.expr[i] == '!') {
            value1 = pop(&value_stack);
            push(&value_stack, !value1);
        }
    }
    return pop(&value_stack);
}

int main() {
    Expr expr = {"(t|f)&!f"};
    expr.len = strlen(expr.expr);
    printf("Result: %d\n", eval(expr));
    return 0;
}

以上为根据栈和队列实现的算数表达式和逻辑表达式求值的两个例子。当然,这两个例子只是简单的示例,在实际的应用中还需要考虑更完善的错误处理机制、数据结构设计等问题。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言中栈和队列实现表达式求值的实例 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • C++ move()函数案例详解

    C++ move()函数案例详解 什么是move()函数? move()函数是C++11中提供的一种对于对象进行右值引用(Rvalue Reference)的操作。该函数能够将对象转换成右值引用,实现对象的移动(Move)而非拷贝(Copy)。 为什么需要move()函数? 在C++的编程过程中,我们经常需要对于对象进行拷贝操作,以便进行如参数传递、返回值传…

    C 2023年5月22日
    00
  • C语言中程序环境和预处理的详细图文讲解

    针对“C语言中程序环境和预处理的详细图文讲解”这一主题,我会为你提供一份完整攻略。本攻略主要分两部分:程序环境和预处理。下面就分别进行详细讲解。 程序环境 什么是程序环境? 程序环境指的是程序执行的环境,包括操作系统、硬件设备等因素。C语言的程序需要在特定的环境下才能执行。 程序的执行过程 当程序运行时,它需要在内存中占用一定的空间。程序在执行过程中分为以下…

    C 2023年5月23日
    00
  • 浅析VSCode tasks.json中的各种替换变量的意思 ${workspaceFolder} ${file} ${fileBasename} ${fileDirname}等

    关于VSCode tasks.json中的各种替换变量,我整理了如下攻略: 一、什么是tasks.json tasks.json是Visual Studio Code中用来指定任务的一个配置文件,可以用来运行一些自定义的构建、测试、调试等任务。在这个配置文件中,可以指定任务的执行命令,参数,以及一些特定的配置项。 二、tasks.json中的替换变量 在指定…

    C 2023年5月23日
    00
  • C语言的动态内存管理你了解吗

    C语言的动态内存管理是非常重要的知识点,掌握了动态内存管理,可以更好地理解程序的运行过程。下面是动态内存管理的完整攻略: 1. 动态内存分配的概念 动态内存分配是在程序运行时向操作系统申请内存空间,对内存进行分配、释放和管理的过程。与静态内存分配不同,静态内存分配在程序编译时就已经确定了。动态内存分配通常用于需要运行时才完成大小和数量的确定的情况下,例如输入…

    C 2023年5月23日
    00
  • C语言入门篇–初识C语言及数据类型

    C语言入门篇–初识C语言及数据类型 一、C语言概述 C语言是一种高级编程语言,它可以编写底层的系统软件和高级的应用程序。它在计算机领域中的优势在于它快速、高效、稳定,且是一种跨平台的语言。 二、数据类型 在C语言中,数据类型用于定义不同类型的变量。C语言提供了许多内置的数据类型,例如int、float、char等等。 1.整数型(int) 整数型是最基本的…

    C 2023年5月23日
    00
  • 优先队列(priority_queue)的C语言实现代码

    优先队列是一种特殊的队列,每个元素都有一个权值。优先队列不同于一般的队列,它不是先进先出,而是按照元素的权值排序,权值最高的元素最先出队列。 C语言中,我们可以使用结构体和数组来实现优先队列。以下是实现优先队列的C语言代码: #include <stdio.h> #include <stdlib.h> typedef struct p…

    C 2023年5月23日
    00
  • C语言中调用汇编语言详解

    C语言和汇编语言是近年来广泛应用于硬件控制、系统底层控制、嵌入式系统等方面的编程语言,由于汇编语言能够直接访问和控制硬件资源,所以在需要对硬件进行底层控制时,常常需要用到汇编语言编写的程序。作为高级语言代表的C语言,也能够和汇编语言进行良好的协同工作。下面将讲解如何在C语言中调用汇编语言。 1.编写汇编程序 在C语言程序中调用汇编语言程序,首先需要编写一个汇…

    C 2023年5月23日
    00
  • java调用外部程序的方法及代码演示

    Java调用外部程序是一种常见场景,我们可以使用Java语言来方便地与外部程序进行交互。在本篇文章中,我将为大家详细讲解Java调用外部程序的方法及代码演示。 一、使用Runtime类调用外部程序 1.1 Runtime.getRuntime().exec()方法 Java提供了Runtime类来处理与系统进程的交互,我们可以使用该类的exec()方法来启动…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部