后缀表达式转中缀表达式(c实现)

原创 2018年04月17日 13:06:45

我们用一个指针栈来实现转换过程。

主要流程大概是这样:每次调用getop函数获取下一个运算符或操作数,然后用栈进行转换。

转换过程:遇见一个数,就将它的地址压入栈中;遇见一个运算符,就弹出对应数目的操作数,再将运算符和对应的操作数连接成一个子表达式,然后将该表达式压入栈中。最后打印栈顶元素即可。(在连接过程中,要在需要加括号的地方加上括号)

对于如何加括号,我举个简单的例子来说明一下:假如栈顶表达式是 3 + 4,而下一个读入的运算符是 *,*的优先级高于+,所以 3 + 4 就需要加上括号。

下面是代码:可能不是太完美,希望大家能提出建议,嘻嘻!


main.c
#include "stdio.h"
#include "ctype.h"
#include "stdlib.h"
#include "string.h"
#include "assert.h"

#define MAXEXP 1000            /*  输入的表达式的最大长度  */
#define MAXOP  100             /*  运算符或操作数的最大长度  */
#define NUMBER '0'             /*  标识找到一个数  */

int getop(char *);
int op_prior(int);

void cat_exp(char *, char *, char *, int, int);
void cat(char *, char *);
int isop(char *);

void push(char *);
void pop(void);
char *top(void);
int isfull(void);
int isempty(void);

int main(int argc, const char *argv[])
{
    int c;
    int lastc;
    char s[MAXEXP];           /*  存储输入的表达式  */
    char *op2;

    lastc = 0;
    while ((c = getop(s)) != EOF)
        if (c == NUMBER)
            push(s);
        else if (op_prior(c)) {
            op2 = top();
            pop();
            cat_exp(top(), s, op2, c, lastc);
            push(s);
            lastc = c;
        } else if (c == '\n') {
            printf("%s\n", top());
            pop();
        }
}

/*  getop函数:从输入中获取下一个运算符或操作数  */
int getop(char *s)
{
    int c;
    int i;
              /*  为了输出形式清晰美观,我们在每个数或运算符后面加上一个空格  */
    while ((s[0] = c = getchar()) == ' ' || c == '\t')
        ;
    if (!isdigit(c) && c != '.') {
        s[1] = ' ';
        s[2] = '\0';
        return c;
    }
    i = 0;
    if (isdigit(c))       
        while (isdigit(s[++i] = c = getchar()))
            ;
    if (c == '.')
        while (isdigit(s[++i] = c = getchar()))
            ;
    s[i] = ' ';
    s[++i] = '\0';
    if (c != EOF)
        ungetc(c, stdin);
    return NUMBER;
}

unexpts.c
/*  cat_exp函数:连接两个子表达式  */
void cat_exp(char *op1, char *s, char *op2, int c, int lastc)
{
    char tmp[MAXOP];
    char op[MAXOP];
    char opt[MAXOP];

    strcpy(tmp, s);
    if (lastc && op_prior(c) > op_prior(lastc)) {
        if (isop(op1)) {
            cat(op, op1);
            op1 = op;
        }        /*  在可能需要加括号的地方都加上括号  */
        if (isop(op2)) {
            cat(opt, op2);
            op2 = opt;
        }
    }
    strcpy(s, op1);
    strcat(s, tmp);
    strcat(s, op2);
    pop();
}

/*  cat函数:在表达式前后加上括号  */
void cat(char *s, char *op)
{
    *s++ = '(';
    while (*op != '\0')
        *s++ = *op++;
    while (*s != ' ')
        s--;
    *s++ = ')';
    *s++ = ' ';
    *s = '\0';
}

/*  isop函数:判断s中是否有运算符  */
int isop(char *s)
{
    while (*s != '\0')
        if (op_prior(*s++))
            return 1;
    return 0;
}

/*  op_prior函数:返回对应运算符的优先级  */
int op_prior(int c)
{
    switch(c) {
    case '*':
    case '/':
    case '%':
        return 2;
        break;
    case '+':
    case '-':
        return 1;
        break;
    default:
        return 0;
        break;
    }
}
stack.c
#define MAXVAL 100

static char *val[MAXVAL];
static int sp = -1;

/*  push函数:将字符串s压入栈中  */
void push(char *s)
{
    if (!isfull())
        assert((val[++sp] = strdup(s)));
    else           /*  将s保存在某个安全的地方  */
        printf("stack is full\n");
}

/*  pop函数:弹出栈顶值  */
void pop(void)
{
    if (!isempty()) {
        free(val[sp]);
        val[sp--] = NULL;
    } else
        printf("stack is empty\n");
}

/*  top函数:返回栈顶值  */
char *top(void)
{
    if (!isempty())
        return val[sp];
    else {
        printf("stack is empty\n");
        return 0;
    }
}

int isfull(void)
{
    return sp == MAXVAL - 1;
}

int isempty(void)
{
    return sp == -1;
}

第一次写博客,希望大家喜欢吐舌头吐舌头吐舌头

编写支持基于代理的防火墙的应用程序

几乎所有的公司都十分关注保护自己的内部网络,以防黑客及入窃者。一种常见的安全措施是完全断开与因特网的连接。如果黑客们不能连接到您的任何一台机器,他们就不能非法进入您的系统。这种策略产生的不利副作用是,...
  • wxyxl
  • wxyxl
  • 2001-05-04 13:24:00
  • 818

栈的应用:中缀表达式转为后缀表达式(c语言实现)

中缀表达式: 中缀表达式(或中缀记法)是一个通用的算术或逻辑公式表示方法, 操作符是以中缀形式处于操作数的中间(例:3 + 4),中缀表达式是人们常用的算术表示方法。 后缀表达式:...
  • keepupblw
  • keepupblw
  • 2014-05-20 11:11:33
  • 6187

c语言实现中缀表达式向后缀表达式转换

  • 2010年11月02日 19:54
  • 4KB
  • 下载

C语言 实现中缀表达式转后缀表达式并求值

大一菜鸟,初学编程,这是我的第一篇博客,希望能用博客记录我的成长之路。 初学数据结构,刚接触链表和栈,看到有中缀表达式转后缀的题就试着实现了一下。下面贴上代码。因为使用的是字符型变量,所以只能计算个位...
  • wait_nothing_alone
  • wait_nothing_alone
  • 2016-04-16 18:48:57
  • 2431

栈练习之C语言中实现中缀转后缀表达式

#include #include #include #include #include "Myatoi.c" extern int myatoi(const char *str); #def...
  • lwb102063
  • lwb102063
  • 2016-06-29 20:37:05
  • 2528

中缀表达式转后缀表达式--C# 代码实现

使用计算机进行表达式的转换 平常我们用的标准四则运算表达式,如“1+(2-3)*4/5”叫做中缀表达式,,, 中缀转后缀表达式的规则是: 从左到右变量中缀表达式的每个数字和符号,若是数字就输出,即...
  • Czhenya
  • Czhenya
  • 2017-09-22 22:23:45
  • 407

利用栈将中缀表达式转换为后缀表达式

  • 2010年07月30日 18:54
  • 4KB
  • 下载

栈——中缀表达式转后缀表达式

中缀表达式转后缀表达式的算法较为简单,采用栈来实现。规则如下: 遇到数字:直接输出遇到'(':压栈遇到')':持续出栈,如果出栈的符号不是'('则输出,否则终止出栈。遇到符号则判断该符号与栈顶符号...
  • girlkoo
  • girlkoo
  • 2013-12-20 09:35:35
  • 20185

C++栈的应用——后缀表达式求值、中缀表达式到后缀表达式的转换

通常我们把栈归为一种基本的数据结构,同时它也是一种线性表结构,也就是说你要自己实现一个栈的数据结构,既可以用数组实现,也可以用链表实现。栈最主要的特点就是“先进后出”,因为栈只有一个入口和出口。...
  • qq_26849233
  • qq_26849233
  • 2017-06-03 09:06:49
  • 2075

中缀表达式转换为后缀表达式 简易实现(c++)(简易表达式计算)

最近在学数据结构,看《数据结构与算法分析》来自学,在看到表 栈 队列这一章的时候发现后缀表达式这个比较好玩的东西,因为以前计算表达式的时候都是直接对中缀表达式进行处理,而且比较麻烦,现在有了后缀表达式...
  • charlie_heng
  • charlie_heng
  • 2017-02-26 19:20:29
  • 1060
收藏助手
不良信息举报
您举报文章:后缀表达式转中缀表达式(c实现)
举报原因:
原因补充:

(最多只允许输入30个字)