数据结构与算法分析-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;
}
运行结果如下图