C语言实现逆波兰式实例

C语言实现逆波兰式实例

逆波兰式是一种数学表达式表示法,也称为后缀表达式。与常见的表达式表示法不同,逆波兰式将操作数放在操作符之前,能够方便地使用栈等数据结构进行表达式的求解。在C语言中实现逆波兰式求值可以采用栈的数据结构进行实现。本文将介绍基于栈的C语言实现逆波兰式的完整攻略。

逆波兰式的基本原理

逆波兰式可以通过以下步骤进行转换:

  1. 从左到右扫描中缀表达式。
  2. 遇到操作符时,将其压入栈中。
  3. 遇到操作数时,将其输出。
  4. 遇到右括号时,将操作符弹出并输出,直到遇到左括号。
  5. 如果遇到其他操作符,判断其与栈顶操作符的优先级关系,如果栈顶操作符的优先级大于该操作符,则将栈顶操作符弹出并输出,再将该操作符压入栈中。
  6. 重复步骤2-5,直到将中缀表达式转换为后缀表达式。

C语言实现逆波兰式的基本步骤

  1. 定义一个栈结构体,包含栈顶指针以及栈的大小等信息。
  2. 定义一个函数,用于将中缀表达式转换为后缀表达式,其中使用栈来维护操作符。
  3. 定义一个函数,用于计算后缀表达式的值,其中使用栈来维护操作数。

示例说明1:将中缀表达式转换为后缀表达式

以下为一个简单的例子:

#include <stdio.h>

#define MAXSIZE 100

typedef enum {
    OP_PLUS = '+',
    OP_MINUS = '-',
    OP_MULTIPLY = '*',
    OP_DIVIDE = '/',
    OP_LEFT_PARENTHESES = '(',
    OP_RIGHT_PARENTHESES = ')',
    OP_END = '\0'
} operator;

typedef struct {
    operator* top;
    operator* stack;
    int size;
} operator_stack;

void operator_push(operator_stack* stack, operator op) {
    if (stack->top - stack->stack >= stack->size) {
        printf("stack is full\n");
        return;
    }
    *(++stack->top) = op;
}

operator operator_pop(operator_stack* stack) {
    if (stack->top == stack->stack) {
        printf("stack is empty\n");
        return OP_END;
    }
    return *(stack->top--);
}

operator operator_top(operator_stack* stack) {
    if (stack->top == stack->stack) {
        printf("stack is empty\n");
        return OP_END;
    }
    return *(stack->top);
}

operator_stack* operator_stack_create(int size) {
    operator_stack* stack = (operator_stack*) malloc(sizeof(operator_stack));
    stack->top = stack->stack - 1;
    stack->stack = (operator*) malloc(sizeof(operator) * size);
    stack->size = size;
    return stack;
}

void operator_stack_destroy(operator_stack* stack) {
    free(stack->stack);
    stack->stack = NULL;
    stack->top = NULL;
    stack->size = 0;
    free(stack);
}

int is_number(char ch) {
    return ch >= '0' && ch <= '9';
}

int is_operator(char ch) {
    return ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')';
}

int is_higher_priority(operator op1, operator op2) {
    switch (op1) {
        case OP_DIVIDE:
        case OP_MULTIPLY:
            return op2 == OP_PLUS || op2 == OP_MINUS;
        case OP_PLUS:
        case OP_MINUS:
            return op2 == OP_LEFT_PARENTHESES;
        case OP_LEFT_PARENTHESES:
        default:
            return 0;
    }
}

void infix_to_postfix(char* infix, char* postfix, int size) {
    operator_stack* stack = operator_stack_create(size);
    operator_push(stack, OP_LEFT_PARENTHESES);
    int i = 0;
    int j = 0;
    while (infix[i] != '\0') {
        char ch = infix[i++];
        if (is_number(ch)) {
            postfix[j++] = ch;
        } else if (is_operator(ch)) {
            if (ch == OP_LEFT_PARENTHESES) {
                operator_push(stack, ch);
            } else if (ch == OP_RIGHT_PARENTHESES) {
                operator top = operator_pop(stack);
                while (top != OP_LEFT_PARENTHESES) {
                    postfix[j++] = top;
                    top = operator_pop(stack);
                }
            } else {
                operator top = operator_top(stack);
                while (is_higher_priority(top, ch)) {
                    postfix[j++] = operator_pop(stack);
                    top = operator_top(stack);
                }
                operator_push(stack, ch);
            }
        } else {
            printf("invalid character: %c\n", ch);
        }
    }
    while (stack->top != stack->stack) {
        postfix[j++] = operator_pop(stack);
    }
    postfix[j] = '\0';
    operator_stack_destroy(stack);
}

int main() {
    char infix[MAXSIZE] = "3+4*5/(6+7)-8";
    char postfix[MAXSIZE];
    infix_to_postfix(infix, postfix, MAXSIZE);
    printf("infix: %s\npostfix: %s\n", infix, postfix);
    return 0;
}

在上面的示例代码中,我们定义了一个操作符栈来维护中缀表达式转换为后缀表达式的过程。其中operator_push、operator_pop和operator_top函数是操作栈的基本函数。is_higher_priority函数用来判断两个操作符的优先级。infix_to_postfix函数用来将中缀表达式转换为后缀表达式。在实际处理过程中,我们通过扫描中缀表达式中每一个字符,然后进行相应的操作。

示例说明2:计算后缀表达式的值

以下为一个简单的例子:

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

#define MAXSIZE 100

typedef enum {
    OP_PLUS = '+',
    OP_MINUS = '-',
    OP_MULTIPLY = '*',
    OP_DIVIDE = '/',
    OP_LEFT_PARENTHESES = '(',
    OP_RIGHT_PARENTHESES = ')',
    OP_END = '\0'
} operator;

typedef struct {
    int* top;
    int* stack;
    int size;
} integer_stack;

void integer_push(integer_stack* stack, int value) {
    if (stack->top - stack->stack >= stack->size) {
        printf("stack is full\n");
        return;
    }
    *(++stack->top) = value;
}

int integer_pop(integer_stack* stack) {
    if (stack->top == stack->stack) {
        printf("stack is empty\n");
        return 0;
    }
    return *(stack->top--);
}

int integer_top(integer_stack* stack) {
    if (stack->top == stack->stack) {
        printf("stack is empty\n");
        return 0;
    }
    return *(stack->top);
}

integer_stack* integer_stack_create(int size) {
    integer_stack* stack = (integer_stack*) malloc(sizeof(integer_stack));
    stack->top = stack->stack - 1;
    stack->stack = (int*) malloc(sizeof(int) * size);
    stack->size = size;
    return stack;
}

void integer_stack_destroy(integer_stack* stack) {
    free(stack->stack);
    stack->stack = NULL;
    stack->top = NULL;
    stack->size = 0;
    free(stack);
}

int is_number(char ch) {
    return ch >= '0' && ch <= '9';
}

int is_operator(char ch) {
    return ch == '+' || ch == '-' || ch == '*' || ch == '/';
}

int apply_operator(int left, int right, operator op) {
    switch (op) {
        case OP_PLUS:
            return left + right;
        case OP_MINUS:
            return left - right;
        case OP_MULTIPLY:
            return left * right;
        case OP_DIVIDE:
            return left / right;
        default:
            printf("invalid operator\n");
            return 0;
    }
}

int evaluate_postfix(char* postfix) {
    integer_stack* stack = integer_stack_create(strlen(postfix) + 1);
    int i = 0;
    while (postfix[i] != '\0') {
        char ch = postfix[i++];
        if (is_number(ch)) {
            integer_push(stack, ch - '0');
        } else if (is_operator(ch)) {
            int right = integer_pop(stack);
            int left = integer_pop(stack);
            integer_push(stack, apply_operator(left, right, ch));
        } else {
            printf("invalid character: %c\n", ch);
        }
    }
    int result = integer_pop(stack);
    integer_stack_destroy(stack);
    return result;
}

int main() {
    char postfix[MAXSIZE] = "345*67+/8-";
    int result = evaluate_postfix(postfix);
    printf("postfix: %s\nresult: %d\n", postfix, result);
    return 0;
}

在上面的示例代码中,我们定义了一个整数栈来维护后缀表达式求值的过程。其中integer_push、integer_pop和integer_top函数是操作栈的基本函数。apply_operator函数用来计算两个操作数的运算结果。evaluate_postfix函数用来计算后缀表达式的值。在实际处理过程中,我们通过扫描后缀表达式中每一个字符,然后进行相应的操作。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言实现逆波兰式实例 - Python技术站

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

相关文章

  • C语言实现简易网络聊天室

    C语言实现简易网络聊天室攻略 1. 简介 在本文中,我们将介绍如何使用C语言实现一个简易的网络聊天室。最终的网络聊天室将包括客户端和服务器端两个部分。客户端可以通过与服务器相连进行多人聊天,服务器将转发客户端发送的消息到其它客户端。 2. 前期准备 在开始编写代码之前,我们需要进行如下准备工作: 2.1 编程环境 C语言是一门编译型语言,因此我们需要准备好C…

    C 2023年5月23日
    00
  • C语言main函数的参数及其返回值详细解析

    C语言main函数的参数及其返回值详细解析 1. main函数的定义 C语言程序中的main函数是程序的入口函数,也是程序执行的起始点。每个C语言程序必须有一个main函数。 main函数的定义如下: int main(int argc, char *argv[]) { // 程序主体代码 return 0; } 其中, int 表示返回值类型, argc …

    C 2023年5月23日
    00
  • C++实现三子棋游戏详细介绍(附代码)

    C++实现三子棋游戏详细介绍(附代码) 简介 本文将介绍如何使用C++语言来实现一个简单的三子棋游戏。三子棋游戏是一种经典的小游戏,规则简单玩法有趣。在这个游戏中,两个玩家将轮流在一个3×3的棋盘上放置自己的棋子,若某个玩家在横、竖、斜三个方向上连续地放置了三个自己的棋子,则该玩家获胜。本文的实现将包括游戏引擎和用户界面,读者可以直接运行实现好的程序进行游戏…

    C 2023年5月24日
    00
  • 电脑蓝屏DMP文件在哪? win10dmp蓝屏文件的打开方法

    电脑蓝屏DMP文件在哪? win10dmp蓝屏文件的打开方法 当我们的电脑系统遭遇蓝屏时,电脑会自动生成一个.DMP文件,该文件内含有电脑蓝屏时相关的信息和错误代码。在解决蓝屏问题时,查看.DMP文件可以帮助我们更快地找到问题所在。本文将讲解.DMP文件的查找以及如何打开.DMP文件。 查找.DMP文件位置 打开文件资源管理器,点击“电脑”(或者“此电脑”,…

    C 2023年5月24日
    00
  • 使用C++程序获取新浪行情数据的方法

    使用C++程序获取新浪行情数据的方法,可以通过以下步骤实现: 1. 将URL转换为API请求 新浪行情数据的接口是以URL的方式提供的。我们需要将URL转换为API请求,以便用C++代码发送请求并获取数据。 例如,要获取某股票代码为”SH600000″的当前行情数据,我们需要访问以下API请求: http://hq.sinajs.cn/list=sh6000…

    C 2023年5月23日
    00
  • C语言实现队列的示例详解

    C语言实现队列的示例详解 简介 队列是一种常用的数据结构,类似于排队,先进先出。C语言中可以使用结构体、数组、指针等方式来实现队列。本文将介绍如何使用数组实现队列。 实现过程 使用数组实现队列需要定义两个指针:一个指向队列头,一个指向队列尾。 1. 定义队列结构体 结构体定义如下,其中front为队列头指针,rear为队列尾指针,maxSize为队列容量,a…

    C 2023年5月23日
    00
  • NBA2KOL奥多姆投篮包怎么样 C级球员投篮包介绍

    NBA2KOL奥多姆投篮包攻略 什么是投篮包? 投篮包是NBA2KOL中的一个重要装备,可以提高球员的投篮能力。 C级球员投篮包是投篮包中较为基础的一种,可以提高C级球员的投篮能力。而奥多姆投篮包则是较为高级的一种投篮包,可以提高高级球员的投篮能力。 奥多姆投篮包的优势 奥多姆投篮包相比普通投篮包有以下优势: 提高了球员的投篮成功率。根据游戏数据显示,使用奥…

    C 2023年5月23日
    00
  • C语言实现歌手比赛系统

    C语言实现歌手比赛系统 系统概述 歌手比赛系统是一款使用C语言实现的命令行程序,旨在为歌手比赛场次提供后台管理功能。该系统可以添加、删除、修改歌手信息,查询歌手列表和评分,并且可以实现对歌手评分的计算和排名。 实现步骤 步骤一:创建数据结构 首先需要定义一个数据结构来存储歌手的信息,数据结构可以用结构体来进行描述。以下是一个示例结构体: typedef st…

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