iT邦幫忙

0

c 結構問題

題目是要把中序轉成後序,接著分別印出後序跟式子最後的答案,目前卡關的地方是沒辦法把後序的式子儲存起來,有用過陣列去嘗試儲存,但還是沒有辦法讀到,想問一下有比較好的方式去儲存後序的資料嗎?(postfix函式是變成後序,eval是將後序的值計算出來)
另外有推薦可以練習c語言的網站或是書籍嗎?還有最近剛接觸python想問有推薦初學者的書籍嗎?

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

#define MAX_STACK_SIZE 100
#define MAX_EXPR_SIZE 100

typedef enum {
    lparen, rparen, plus, minus, times, divide, mod, eos, operand
} precedence;

static int isp[] = { 0, 19, 12, 12, 13, 13, 13, 0 };
static int icp[] = { 20, 19, 12, 12, 13, 13, 13, 0 };

precedence stack[MAX_STACK_SIZE];
char expr[MAX_EXPR_SIZE];

precedence stack_empty() {
    fprintf(stderr, "error: stack is empty\n");
    return -1;
}

void stack_full() {
    fprintf(stderr, "error: stack is full\n");
}

/* return the top element from the stack */
precedence delete(int *top) {
    if (*top == -1)
        /* returns an error key */
        return stack_empty();
    return stack[(*top)--];
}

/* add an item to the global stack */
void add(int *top, int item) {
    if (*top >= MAX_STACK_SIZE - 1)
        return stack_full();
    (*top)++;
    stack[*top] = item;
}

/* get the next token, symbol is the character representation, which is
 * returned, the token is represented by its enumerated value, which is
 * returned in the function name */
precedence get_token(char *symbol, int *n) {
    *symbol = expr[(*n)++];
    switch (*symbol) {
        case '(' : return lparen;
        case ')' : return rparen;
        case '+' : return plus;
        case '-' : return minus;
        case '/' : return divide;
        case '*' : return times;
        case '%' : return mod;
        case '\0': return eos;
        default  : return operand; /* no error checking, default is operand */
    }
}

void print_token(precedence token) {
    switch (token) {
        case lparen: printf("("); break;
        case rparen: printf(")"); break;
        case plus  : printf("+"); break;
        case minus : printf("-"); break;
        case times : printf("*"); break;
        case divide: printf("/"); break;
        case mod   : printf("%%"); break;
        default    : break;
    }
}

/* output the postfix of the expression. The expression string, the stack, and
 * top are global */
void postfix(void) {
    char symbol;
    precedence token;
    int n = 0;
    int top = 0; /* place eos  on stack */
    stack[0] = eos;
    for (token = get_token(&symbol, &n);
         token != eos;
         token = get_token(&symbol, &n)) {
        if (token == operand)
            printf("%c", symbol);
        else if (token == rparen) {
            /* unstack tokens until left parenthesis */
            while (stack[top] != lparen)
                print_token(delete(&top));
            delete(&top); /* discard the left parenthesis */
        }
        else {
            /* remove and print symbol whose  isp is greater than or equal to
             * the current token’s icp */
            while (isp[stack[top]] >= icp[token])
               print_token(delete(&top));
               /*print_token(token);*/
            add(&top, token);
        }
    }
    while ((token = delete(&top)) != eos)
        print_token(token);
    printf("\n");
}
int eval(void) {
    precedence token;
    char symbol;
    int op1, op2;
    int n = 0; /* counter for the expression string */
    int top = -1;
    token = get_token(&symbol, &n);

    while (token != eos) {
        if (token == operand)
            add(&top, symbol - '0'); /* stack insert */
        else {
            /* remove two operands, perform operation, and return result to the stack */
            op2 = delete(&top); /* stack delete */
            op1 = delete(&top);
            switch (token) {
                case plus: add(&top, op1 + op2);
                           break;
                case minus: add(&top, op1 - op2);
                            break;
                case times: add(&top, op1 * op2);
                            break;
                case divide: add(&top, op1 / op2);
                             break;
                case mod: add(&top, op1 % op2);
            }
        }
        token = get_token(&symbol, &n);
    }
    return delete(&top); /* return result */
}
int main() {
    while (scanf(" %s", expr) != EOF) {
        postfix();
        printf("%d\n", eval());
    }
    return 0;
}

最後的結果希望是這樣https://ithelp.ithome.com.tw/upload/images/20210416/20132864Pn5qPh1BFI.jpg

小魚 iT邦大師 1 級 ‧ 2021-04-17 12:10:19 檢舉
3+2變32...
可能要先把字串轉成數字...
abalun52 iT邦新手 5 級 ‧ 2021-04-17 13:22:42 檢舉
現在是已經印出32+8*了但是不知道該怎麼將這些資料儲存去計算下面的40

尚未有邦友回答

立即登入回答