#include #include #include #include #include #define MAX 100 // === 全域變數宣告 === char input[MAX]; char postfix[MAX]; char stack[MAX]; double numStack[MAX]; int top = -1; int numTop = -1; // === 函式宣告 === int get_priority(char op); int is_operator(char c); double calculate(double a, double b, char op); void convert_to_postfix(); double evaluate_postfix(); // === 檢查運算子優先順序 === int get_priority(char c){ if(c=='+' || c=='-'){ return 1; }else if(c=='*' || c=='/'){ return 2; }else if(c=='^'){ return 3; }else{ return 0; } } // === 檢查字元是否為運算子 === int is_operator(char c) { return (c == '+' || c == '-' || c == '*' || c == '/' || c == '^'); } // === 執行運算 === double calculate(double a, double b, char op) { switch(op) { case '+': return a + b; case '-': return a - b; case '*': return a * b; case '/': if(b != 0) return a / b; printf("錯誤:除數不能為零!\n"); exit(1); case '^': return pow(a, b); default: return 0; } } // === 轉換為後序表達式 === void convert_to_postfix() { int i = 0, j; int postfix_index = 0; top = -1; char number_str[MAX]; int is_negative; while(input[i] != '\0') { if(isdigit(input[i]) || input[i] == '.' || (input[i] == '-' && (i == 0 || input[i-1] == '(' || is_operator(input[i-1])))) { // 處理數字(包括負數) is_negative = 0; int num_len = 0; // 檢查是否為負數 if(input[i] == '-') { is_negative = 1; i++; } // 收集完整數字字串 while(input[i] != '\0' && (isdigit(input[i]) || input[i] == '.')) { number_str[num_len++] = input[i++]; } number_str[num_len] = '\0'; i--; // 回退一個位置,因為外層 while 會再加一 // 輸出數字 printf("%s ", number_str); if(is_negative) { printf("- "); } // 將數字加入後序表達式 for(j = 0; j < num_len; j++) { postfix[postfix_index++] = number_str[j]; } postfix[postfix_index++] = ' '; if(is_negative) { postfix[postfix_index++] = '-'; postfix[postfix_index++] = ' '; } } else if(input[i] == '(') { stack[++top] = input[i]; } else if(input[i] == ')') { while(top >= 0 && stack[top] != '(') { printf("%c ", stack[top]); postfix[postfix_index++] = stack[top]; postfix[postfix_index++] = ' '; top--; } if(top >= 0) top--; } else if(is_operator(input[i])) { // 如果不是處理負數的減號 if(!(input[i] == '-' && (i == 0 || input[i-1] == '(' || is_operator(input[i-1])))) { while(top >= 0 && stack[top] != '(' && (get_priority(stack[top]) > get_priority(input[i]) || (get_priority(stack[top]) == get_priority(input[i]) && input[i] != '^'))) { printf("%c ", stack[top]); postfix[postfix_index++] = stack[top]; postfix[postfix_index++] = ' '; top--; } stack[++top] = input[i]; } } i++; } while(top >= 0) { printf("%c ", stack[top]); postfix[postfix_index++] = stack[top]; postfix[postfix_index++] = ' '; top--; } postfix[postfix_index] = '\0'; printf("\n"); } // === 計算後序表達式 === double evaluate_postfix() { int i; numTop = -1; char *token = strtok(postfix, " "); printf("\n計算過程:\n"); while(token != NULL) { printf("處理標記:'%s'\n", token); if(isdigit(token[0]) || (token[0] == '-' && isdigit(token[1]))) { double num = atof(token); numStack[++numTop] = num; printf("壓入數字:%.2f\n", num); } else if(is_operator(token[0])) { if(numTop < 1) { printf("錯誤:運算子 '%c' 缺少足夠的操作數\n", token[0]); exit(1); } double b = numStack[numTop--]; double a = numStack[numTop--]; double result = calculate(a, b, token[0]); numStack[++numTop] = result; printf("計算:%.2f %c %.2f = %.2f\n", a, token[0], b, result); } else { printf("錯誤:未知的標記 '%s'\n", token); exit(1); } printf("當前堆疊:"); for(i = 0; i <= numTop; i++) { printf("%.2f ", numStack[i]); } printf("\n\n"); token = strtok(NULL, " "); } if(numTop != 0) { printf("錯誤:計算結束後堆疊中剩餘 %d 個元素\n", numTop + 1); exit(1); } return numStack[numTop]; } int main() { printf("請輸入中序表示式(支援+-*/^()運算) => "); fgets(input, MAX, stdin); input[strcspn(input, "\n")] = 0; printf("\n對應的後序表示法式: "); convert_to_postfix(); double postfix_result = evaluate_postfix(); printf("\n運算結果:%.2f", postfix_result); printf("\t(正確值為:"); if(strcmp(input,"10+20*(50-30)/2^4-6*8")==0){ printf("%g",10+20*(50-30)/pow(2,4)-6*8); }else if(strcmp(input,"10+20*(-50+30)/-2^4-6*8")==0){ printf("%g",10+20*(-50+30)/pow(-2,4)-6*8); }else if(strcmp(input,"10.5+20.8*(50.1-30.6)/2.5^4-6.6*8.2")==0){ printf("%g",10.5+20.8*(50.1-30.6)/pow(2.5,4)-6.6*8.2); }else if(strcmp(input,"10.5+20.8*(-50.1+30.6)/2.5^-4-6.6*8.2")==0){ printf("%g",10.5+20.8*(-50.1+30.6)/pow(2.5,-4)-6.6*8.2); } printf(")"); return 0; }