自己编的中缀表达式转后缀表达式(C语言),供参考,指证

 

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

#define MAX 100
char string1[MAX];
char string2[MAX];
typedef struct LNode {
    char a;
    struct LNode *next;
} StackNode;

typedef struct {
    StackNode *top;
} LinedkStack;

void InitStack(LinedkStack &S) {
    S.top = (StackNode *) malloc(sizeof(StackNode));
    S.top = 0;
}

void push(LinedkStack &S, char e) {
    StackNode *p;
    p = (StackNode *) malloc(sizeof(StackNode));
    p->a = e;
    p->next = NULL;
    p->next = S.top;
    S.top = p;
}

int pop(LinedkStack &S) {
    StackNode *p;
    char e;
    if (NULL != S.top) {
        p = S.top;
        e = p->a;
        S.top = p->next;
        free(p);
        return 1;
    } else
        return 0;
}

char read(LinedkStack &L) {
    char e;
    if (L.top != NULL) {
        e = L.top->a;
    } else {
        e = '#';
    }
    return e;
}

typedef struct {
    double data[MAX];
    int top;
} SeqStack;

void InitStack(SeqStack &S) {
    S.top = 0;
}

void SeqPush(SeqStack &S, double e) {
    if (S.top > MAX) {
        printf("栈已满!\n");
    } else
        S.data[S.top] = e;
    S.top++;
}

double SeqPop(SeqStack &S) {
    double e;
    if (S.top == 0) {
        printf("栈为空!\n");
    } else {
        S.top--;
        e = S.data[S.top];
    }
    return e;
}

int set(char e) {
    int p;
    switch (e) {
        case '#':
            p = 1;
            break;
        case '(':
            p = 2;
            break;
        case '+':
        case '-':
            p = 3;
            break;
        case '*':
        case '/':
        case '%':
            p = 4;
            break;
        case ')':
            p = 5;
            break;
        default:
            printf("你输入的符号不存在,请从新输入!\n");
            gets(string1);
            break;
    }
    return p;
}

void fix(char b[], char c[]) {
    LinedkStack L;
    char ch, ca;
    int i = 0, j = 0, k, d, m;
    InitStack(L);
    push(L, '#');
    m = strlen(b);
    ch = b[i];
    i++;
    for (; i <= m;) {
        ca = read(L);
        if (ch < '0' || ch > '9') {
            k = set(ch);
            d = set(read(L));
            if (k > d) {
                if (ch == ')') {
                    ca = read(L);
                    j--;
                    while (ca != '(') {
                        pop(L);
                        j++;
                        c[j] = ca;
                        j++;
                        c[j] = ',';
                        ca = read(L);
                    }
                    pop(L);
                    ch = b[i];
                    i++;
                    j++;
                } else {
                    push(L, ch);
                    ch = b[i];
                    i++;
                }
            } else {
                if (ch != '(') {
                    ca = read(L);
                    c[j] = ca;
                    j++;
                    c[j] = ',';
                    j++;
                    pop(L);
                    continue;
                }
                push(L, ch);
                ch = b[i];
                i++;
            }
        } else {
            while (ch >= '0' && ch <= '9') {
                c[j] = ch;
                j++;
                ch = b[i];
                i++;
            }
            c[j] = ',';
            j++;
        }
    }
    ca = read(L);
    while (ca != '#') {
        c[j] = ca;
        j++;
        c[j] = ',';
        j++;
        pop(L);
        ca = read(L);
    }
    c[--j] = '\0';
}

double cal(char b[]) {
    SeqStack S;
    InitStack(S);
    char ca[15];
    int i = 0, j = 0;
    double x1 = 0, x2 = 0, v;
    while (b[i] != '\0') {
        if (b[i] >= '0' && b[i] <= '9' && b[i] != ',') {
            j = 0;
            memset(ca, '\0', sizeof(ca));
            while (b[i] != ',') {
                ca[j] = b[i];
                i++;
                j++;
            }
            v = atol(ca);
            SeqPush(S, v);
        } else {
            v = 0;
            switch (b[i]) {
                case ',':
                    break;
                case '+':
                    x1 = SeqPop(S);
                    x2 = SeqPop(S);
                    v = x2 + x1;
                    SeqPush(S, v);
                    break;
                case '-':
                    x1 = SeqPop(S);
                    x2 = SeqPop(S);
                    v = x2 - x1;
                    SeqPush(S, v);
                    break;
                case '*':
                    x1 = SeqPop(S);
                    x2 = SeqPop(S);
                    v = x2 * x1;
                    SeqPush(S, v);
                    break;
                case '/':
                    x1 = SeqPop(S);
                    x2 = SeqPop(S);
                    if (x1 == 0.0) {
                        printf("出现除0错误,请从新输入!\n");
                        gets(string1);
                    } else {
                        v = x2 / x1;
                        SeqPush(S, v);
                    }
                    break;
                case '%':
                    int x1 = SeqPop(S);
                    int x2 = SeqPop(S);
                    v = x2 % x1;
                    SeqPush(S, v);
                    break;
            }
            i++;
        }
    }
    v = SeqPop(S);
    return v;
}

void main() {
    int n, m;
    double f;
    char sr[MAX];
    printf("请输入中缀表达式:\n");
    gets(string1);
    m = strlen(sr);
    for (n = 0; n <= m; n++) {
        sr[n] = string1[n];
        if (string1[n] == '%' && string1[n + 1] == '-') {
            printf("求余号后面有减号,请从新输入!\n");
            gets(string1);
        }
    }
    fix(string1, string2);
    printf("后缀表达式:\n%s\n", string2);
    f = cal(string2);
    printf(" 计算结果:\n%lf\n", f);
}

 

中缀表达式转后缀表达式C语言代码可以通过使用栈来实现。具体步骤如下: 1. 从左到右扫描中缀表达式的每个元素。 2. 如果当前元素是操作数,直接输出到后缀表达式中。 3. 如果当前元素是左括号,将其压入栈中。 4. 如果当前元素是右括号,将栈中的元素弹出并输出到后缀表达式中,直到遇到左括号。 5. 如果当前元素是操作符,比较其与栈顶操作符的优先级,如果当前操作符优先级高于栈顶操作符,将其压入栈中。 6. 如果当前操作符优先级低于或等于栈顶操作符,将栈顶操作符弹出并输出到后缀表达式中,然后再次比较当前操作符与新的栈顶操作符的优先级,直到当前操作符可以被压入栈中。 7. 重复步骤1~6,直到中缀表达式扫描完毕。 8. 如果栈中还有操作符,依次弹出并输出到后缀表达式中。 下面是中缀表达式转后缀表达式C语言代码实现: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_SIZE 100 typedef struct { char data[MAX_SIZE]; int top; } Stack; // 初始化栈 void init(Stack *s) { s->top = -1; } // 判断栈是否为空 int is_empty(Stack *s) { return s->top == -1; } // 判断栈是否已满 int is_full(Stack *s) { return s->top == MAX_SIZE - 1; } // 入栈 void push(Stack *s, char c) { if (is_full(s)) { printf("Stack Overflow\n"); exit(1); } s->data[++s->top] = c; } // 出栈 char pop(Stack *s) { if (is_empty(s)) { printf("Stack Underflow\n"); exit(1); } return s->data[s->top--]; } // 获取栈顶元素 char peek(Stack *s) { if (is_empty(s)) { printf("Stack Underflow\n"); exit(1); } return s->data[s->top]; } // 判断是否为操作符 int is_operator(char c) { return c == '+' || c == '-' || c == '*' || c == '/'; } // 获取操作符优先级 int get_precedence(char c) { if (c == '+' || c == '-') { return 1; } else if (c == '*' || c == '/') { return 2; } else { return 0; } } // 中缀表达式转后缀表达式 char* infix_to_postfix(char *infix) { Stack s; init(&s); int length = strlen(infix); char *postfix = (char*)malloc(sizeof(char) * length); int j = 0; for (int i = 0; i < length; i++) { char c = infix[i]; if (is_operator(c)) { while (!is_empty(&s) && is_operator(peek(&s)) && get_precedence(peek(&s)) >= get_precedence(c)) { postfix[j++] = pop(&s); } push(&s, c); } else if (c == '(') { push(&s, c); } else if (c == ')') { while (!is_empty(&s) && peek(&s) != '(') { postfix[j++] = pop(&s); } pop(&s); } else { postfix[j++] = c; } } while (!is_empty(&s)) { postfix[j++] = pop(&s); } postfix[j] = '\0'; return postfix; } int main() { char infix[MAX_SIZE]; printf("Enter an infix expression: "); fgets(infix, MAX_SIZE, stdin); char *postfix = infix_to_postfix(infix); printf("Postfix expression: %s\n", postfix); free(postfix); return 0; } ``` 注意,以上代码中的`fgets()`函数可以保证输入不会超过`MAX_SIZE`的限制。如果使用`scanf()`函数,需要对输入进行有效性检查,以避免缓冲区溢出等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值