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日

相关文章

  • VS Code+msys2配置Windows系统下C/C++开发环境

    下面就是关于“VS Code+msys2配置Windows系统下C/C++开发环境”的完整攻略。 第一步:安装必要软件 首先,我们需要下载并安装以下软件: Visual Studio Code msys2 MinGW-w64 其中,Visual Studio Code是一款优秀的开源代码编辑器;msys2是一个包含大量 Unix/Linux 工具和库的环境,…

    C 2023年5月23日
    00
  • C++中的对象初始化操作代码

    下面就来详细讲解一下 C++ 中的对象初始化操作代码的完整攻略。 什么是对象初始化 在 C++ 中,定义一个对象后不仅要申请存储空间,还需要对对象进行赋值或初始化,以便使其具备正确的初始值和状态。对象初始化即是给刚申请的存储空间一个初始值和状态的过程,其作用是为了确保程序的正确性和安全性。因此,在使用对象之前应确保其已被正确初始化。 对象初始化方式 在 C+…

    C 2023年5月23日
    00
  • Qt跨平台窗口选择功能的实现过程

    Qt跨平台窗口选择功能的实现 在Qt中,实现跨平台窗口选择功能通常需要调用QWidget的setWindowFlags()函数,并传递一个标志参数。本文将详细介绍该功能的实现过程。 1. setWindowFlags()函数简介 setWindowFlags()是Qt中QWidget类的成员函数,该函数用于设置窗口的标志。在跨平台窗口选择功能的实现过程中,我…

    C 2023年5月23日
    00
  • C语言实现简单图书管理系统

    C语言实现简单图书管理系统详细攻略 系统功能需求 一个简单的图书管理系统功能需求为: 借阅图书:用户能够借阅图书。 归还图书:用户能够归还图书。 查看图书:用户能够查看系统中的所有图书。 增加图书:管理员能够增加新的图书到系统中。 删除图书:管理员能够删除系统中已有的图书。 修改图书:管理员能够修改系统中已有的图书。 实现思路 创建一个图书结构体,包含图书的…

    C 2023年5月23日
    00
  • C++用函数对算法性能进行测试

    下面是我对于“C++用函数对算法性能进行测试”的完整攻略: 1. 为什么要测试算法性能? 在进行算法设计的过程中,我们需要考虑算法的正确性和效率。算法的正确性很容易通过测试样例来验证,但是效率比较难以直接衡量。因此,我们需要对算法的性能进行测试,以便更全面地评估算法的优劣。 2. 性能测试的方法和工具 在进行性能测试之前,我们需要知道如何来测试算法的性能。下…

    C 2023年5月23日
    00
  • Objective-C的NSOperation多线程类基本使用指南

    下面是关于“Objective-C的NSOperation多线程类基本使用指南”的完整攻略: 简介 在iOS开发中,多线程是一个常用的技术,可以有效地提高程序的效率和响应速度。Objective-C提供了多种多线程的实现方式,其中NSOperation是一种高级的多线程技术,它可以让我们更加方便地实现多线程操作。 NSOperation是一个抽象类,我们可以…

    C 2023年5月22日
    00
  • C++中strstr函数的实现方法总结

    C++中strstr函数的实现方法总结 什么是strstr函数 strstr函数是C/C++中的字符串函数之一,用于在字符串中查找子串。其原型如下: char * strstr ( const char * str1, const char * str2 ); 它的功能是在 str1 字符串中查找第一次出现 str2 字符串的位置,如果未找到则返回null。…

    C 2023年5月24日
    00
  • Linux系统下C语言gets函数出现警告问题的解决方法

    以下是详细讲解 “Linux系统下C语言gets函数出现警告问题的解决方法”的完整攻略。 1. gets函数警告问题 在 Linux 系统下使用 C 语言进行编程时,我们有时会使用 gets 函数,但是这种函数在读取字符串时很容易造成缓冲区溢出,导致程序崩溃。因此,编译器会提示警告信息,防止程序出错。 下面是使用 gets 函数的示例代码: #include…

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