中缀表达式转化后缀表达式

数据结构与算法分析-C语言描述 -p54 页,讲述了中缀表达式使用堆栈方式转化成后缀表达式.
后缀表达式用来实现计算四则运算.
具体思路是:
1.遇到运算符,
2.跟栈顶元素比较,
3.优先级比栈顶的高 转5.
4.小于或者相等则栈顶弹出,转2.
5.当前运算符进栈.
对’(’ ')'这里的处理取巧使用了递归方式,不用考虑跟上一级的复杂的关系
下面是源码: (方式有点蠢,谁叫我着急呢,后面再改进,GDB太难用,还是打印大法好)

#include "string.h"
#include "stdlib.h"
#include "stdio.h"

char recv_buffer[1024];
char send_buffer[1024];

typedef unsigned char bool;

#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif

typedef struct 
{
    /* data */
    char* operator;
    int precedence;
} operator_precede_t;

typedef struct {
   operator_precede_t op_pre[128];
   int top;
} operator_stack_t;

typedef enum{
    ERR_NOTHING,
    ERR_EXPREES_BREAK_RULES,
    ERR_UNKNOW_OPERATOR_CMP,
    ERR_OPERATOR_STACK_PUSH_FULL,
    ERR_OPERATOR_STACK_POP_EMPTY,
} err_express_code_t;
err_express_code_t last_err_code;

void set_err_code(err_express_code_t code)
{
    last_err_code = code;
}

err_express_code_t get_err_code(void)
{
    return last_err_code;
}

operator_precede_t operator_precedence_tbl[] =
{
    {"(", 1}, {")", 1},
    {"/", 3}, {"*", 3},
    {"+", 4}, {"-", 4},
    {"=", 14},  
};
#define OPERATOR_PRECEDEENCE_TABLE_NUM      (sizeof(operator_precedence_tbl)/sizeof(operator_precede_t))

bool match_operator(char* s, operator_precede_t* operator)
{
    int i;
    for(i = 0; i < OPERATOR_PRECEDEENCE_TABLE_NUM; i++)
    {
        if (!strncmp(s, operator_precedence_tbl[i].operator, strlen(operator_precedence_tbl[i].operator)))
        {
            memcpy(operator, &operator_precedence_tbl[i], sizeof(operator_precede_t));
            return true;
        }
    }

    return false;
}

bool push_operator_stack(operator_stack_t *operator_stack, operator_precede_t* operator)
{
    if (operator_stack->top < 127)
    {
       memcpy(&operator_stack->op_pre[operator_stack->top++], operator, sizeof(operator_precede_t));
       return true;
    }
    else
    {
        set_err_code(ERR_OPERATOR_STACK_PUSH_FULL);
        return false;
    }
}

bool pop_operator_stack(operator_stack_t *operator_stack, operator_precede_t* operator)
{
    if (operator_stack->top > 0)
    {
       memcpy(operator, &operator_stack->op_pre[operator_stack->top - 1], sizeof(operator_precede_t));
       operator_stack->top--;
       return true;
    }
    else
    {
        set_err_code(ERR_OPERATOR_STACK_POP_EMPTY);
        return false;
    }
}

bool get_operator_stack_top(operator_stack_t *operator_stack, operator_precede_t* operator)
{
    if (operator_stack->top > 0) {
        memcpy(operator, &operator_stack->op_pre[operator_stack->top - 1], sizeof(operator_precede_t)); 
        return true;
    }
    else {
        return false;
    }
}

char* copy_operator(char* dst, operator_precede_t* s)
{
    char *src = s->operator;
    while(*src != '\0') {
        *dst++ = *src++;
    }
    return dst;
}


int express_prefix_trans_suffix(char* express_prefix, char* express_suffix)
{
    char* prefix_pointer = express_prefix;
    char* suffix_pointer = express_suffix;
    operator_precede_t operator1, operator2;
    int ret;
    operator_stack_t operator_stack;
    memset(&operator_stack, 0 , sizeof(operator_stack_t));

    printf("entry express transd\n");
    while(*prefix_pointer != '\0')
    {
        ret = match_operator(prefix_pointer, &operator1);
        if (true == ret) {
            printf("match_operator: %s\n", operator1.operator);
            if (!strcmp(operator1.operator, "(")) {
                printf("operator \"(\" detect\n");
		ret = express_prefix_trans_suffix(prefix_pointer + 1, suffix_pointer);
                if (ret < 0) {
                    return ret;
                }
                //adjust pointer
                while(*prefix_pointer != '\0' && *prefix_pointer != ')') {
                    prefix_pointer++;
                    if (prefix_pointer > recv_buffer+1024) {
                        return -ERR_EXPREES_BREAK_RULES;
                    }
                };
                if (*prefix_pointer == '\0') {
                   break;
                }
                prefix_pointer++;
                while(*suffix_pointer != '\0') {
                    suffix_pointer++;
                }
                continue;
            }
            if (!strcmp(operator1.operator, ")")) {
                printf("operator \")\" detect\n");
                goto end;
            }
            do {
                bool ret = get_operator_stack_top(&operator_stack, &operator2);
                //if top or cur precdence higher than top, do push, else pop
                if (true == ret) {
                    printf("get operator stack pop: %s\n", operator2.operator);
                    printf("operator current %s stack top %s\n", operator1.operator, operator2.operator);
                    if (operator1.precedence >= operator2.precedence) 
                    {
                        printf("pop operator stack %s\n", operator2.operator);
                        pop_operator_stack(&operator_stack, &operator2);
                        if (!strcmp(operator2.operator, ")")) {
                            printf("operator \")\" force update cancel\n");
                            continue;
                        }
                        suffix_pointer = copy_operator(suffix_pointer, &operator2);
                        printf("copy to suffix buffer: %s\n", send_buffer);
                    }
                    else
                    {
                        printf("push operator stack %s\n", operator1.operator);
                        if (false == push_operator_stack(&operator_stack, &operator1))
                        {
                            return -get_err_code();
                        }
                        break;
                    }
                }
                else {
                    printf("operator stack empty\n");
                    printf("push operator stack %s\n", operator1.operator);
                    if (false == push_operator_stack(&operator_stack, &operator1))
                    {
                        return -get_err_code();
                    }
                    break;     
                }
            } while (1);
        }
        else {
            *suffix_pointer++ = *prefix_pointer;
            printf("copy to suffix buffer: %s\n", send_buffer);
        }
        prefix_pointer++;
    }

end:
    while(true == pop_operator_stack(&operator_stack, &operator2)) {
        suffix_pointer = copy_operator(suffix_pointer, &operator2);
        printf("copy to suffix buffer: %s\n", send_buffer);
    }

    printf("leave express transd\n");
    return 0;
}

int get_line(char* buf, int max_size)
{
    int cnt = 0;
    *buf = '\0';
    while(1) {
        char c = getchar();
        if (c == '\n') {
            *buf++ = '\0';
            break;
        }
        if (c == ' ') {
            continue;
        }
        //printf("%c", c);
        *buf++ = c;
        cnt++;
        if(cnt == 1023) {
            break;
        }
    }
    return cnt;
}

int main(int argc, char* argv[])
{
    int ret;
    memset(recv_buffer, 0, 1024);
    memset(send_buffer, 0, 1024);

    if (get_line(recv_buffer, 1024) > 0) 
    {
        printf("prefix: %s\n", recv_buffer);
        ret = express_prefix_trans_suffix(recv_buffer, send_buffer);
        if (ret == 0) {
            printf("suffix: %s\n", send_buffer);
        }
        else {
            printf("err code: %d\n", ret);
        }
    }

    getchar();

    return 0;
}

运行结果如下图
prefix2suffix.jpg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值