程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言:逆波蘭表達式代碼

C語言:逆波蘭表達式代碼

編輯:關於C語言

今天有師妹求助,要實現帶有括號、加減乘除、階乘的表達式計算

一時沖動便給師妹寫了一下,C語言代碼如下,用了兩個棧來實現逆波蘭表達式求值:

[c]
//
#include <stdio.h> 
#include <stdlib.h> 
//運算符棧的長度 
#define OPSTACK_LENGTH 5 
//操作數棧的長度 
#define NUMSTACK_LENGTH 100 
//輸入串的最大長度 
#define MAX_STRING_LENGTH 100 
 
//運算符結構體 
struct operatorStruct 

    //運算符名稱 
    char name; 
    //優先級 
    int priority; 
    //目數,即操作數個數,例如單目運算符為1,雙目運算符2 
    int opnum; 
}; 
 
typedef struct operatorStruct OPERATOR; 
 
//運算符棧 
OPERATOR opStack[OPSTACK_LENGTH]; 
//運算符棧頂指針 
int opStackTop = -1; 
//操作數棧 
double numStack[NUMSTACK_LENGTH]; 
//操作數棧頂指針 
int numStackTop = -1; 
 
//獲取一個字符所代表的運算符的優先級 
int getPriority(char name) 

    if (name == '(' || name == ')') 
    { 
        return 0; 
    } 
    if (name == '!') 
    { 
        return 3; 
    } 
    if (name == '*' || name == '/') 
    { 
        return 2; 
    } 
    if (name == '+' || name == '-') 
    { 
        return 1; 
    } 
    exit(1); 

//獲取一個字符所代表的運算符的目數 
int getOpNum(char name) 

    if (name == '*' || name == '/' || name == '+' || name == '-') 
    { 
        return 2; 
    } 
    if (name == '!') 
    { 
        return 1; 
    } 
    if (name == '(' || name == ')') 
    { 
        return 0; 
    } 
    exit(1); 

 
//運算符壓棧 
void pushOperator(OPERATOR op) 

    if (opStackTop < OPSTACK_LENGTH - 1) 
    { 
        opStack[++opStackTop] = op; 
    } 
    else 
    { 
        exit(1); 
    } 

//運算符出棧 
OPERATOR popOperator() 

    if (opStackTop >= 0) 
    { 
        return opStack[opStackTop--]; 
    } 
    else 
    { 
        exit(1); 
    } 

//操作數壓棧 
void pushNumber(double num) 

    if (numStackTop < NUMSTACK_LENGTH - 1) 
    { 
        numStack[++numStackTop] = num; 
    } 
    else 
    { 
        exit(1); 
    } 

//操作數出棧 
double popNumber() 

    if (numStackTop >= 0) 
    { 
        return numStack[numStackTop--]; 
    } 
    else 
    { 
        exit(1); 
    } 

//將輸入字符串中的以0-9開頭、到下一個運算符結束的一段轉化為浮點型 
//i加上浮點型對應的字符串的長度 
double getNumFromString(char *s, int *i) 

    int j = 0; 
    static char numstr[MAX_STRING_LENGTH]; 
    while ((*s) >= '0' && *s <= '9') 
    { 
        numstr[j++] = (*s); 
        s++; 
    } 
    if ((*s) == '.') 
    { 
        numstr[j++] = (*s); 
        s++; 
        while ((*s) >= '0' && *s <= '9') 
        { 
            numstr[j++] = (*s); 
            s++; 
        } 
    } 
    (*i) = (*i) + j; 
    numstr[j] = '\0'; 
    return atof(numstr); 

 
//從操作數棧中彈出兩個操作數,完成一次雙目運算 
double opertate2Num(OPERATOR op) 

    double num2 = popNumber(); 
    double num1 = popNumber(); 
    if (op.name == '+') 
    { 
        return num1 + num2; 
    } 
    if (op.name == '-') 
    { 
        return num1 - num2; 
    } 
    if (op.name == '*') 
    { 
        return num1 * num2; 
    } 
    if (op.name == '/') 
    { 
        return num1 + num2; 
    } 
    exit(1); 

//從操作數棧中彈出一個操作數,完成一次單目運算 
double opertate1Num(OPERATOR op) 

    double num = popNumber(); 
    if (op.name == '!') 
    { 
        double result = 1; 
        while (num > 1) 
        { 
            result *= num; 
            num--; 
        } 
        return result; 
    } 
    exit(1); 

//完成一次運算 www.2cto.com
double operate(OPERATOR op) 

    if (op.opnum == 1) 
    { 
        return opertate1Num(op); 
    } 
    else if (op.opnum == 2) 
    { 
        return opertate2Num(op); 
    } 
    exit(1); 

 
int main() 

    char string[MAX_STRING_LENGTH];//表達式的輸入串 
    int i; 
    OPERATOR op, topOp;//op為從當前輸入串中提取的一個運算符,topOp為運算符棧棧頂的運算符 
     
    topOp.name = '#'; 
    topOp.priority = 0; 
    topOp.opnum = 0; 
    pushOperator(topOp);//壓入#作為初始運算符 
     
    scanf("%s", string); 
    for (i = 0; string[i] != '\0' && string[i] != '=';) 
    { 
        //從輸入串中取出一個字符作為開始,進行處理,直到表達式結束 
        if (string[i] >= '0' && string[i] <= '9') 
        { 
            //如果是操作數,將整個操作數提取出來,壓入操作數棧 
            pushNumber(getNumFromString(&string[i], &i)); 
        } 
        else 
        { 
            op.name = string[i]; 
            op.priority = getPriority(string[i]); 
            op.opnum = getOpNum(string[i]); 
            topOp = popOperator(); 
            if (op.name == '(') 
            { 
                //如果是'(',將從棧頂彈出的運算符壓回棧內,並將當前運算符則壓棧 
                pushOperator(topOp); 
                pushOperator(op); 
            } 
            else if (op.name == ')') 
            { 
                //如果是')',則進行運算,每次運算結果作為一個操作數壓入操作數棧,直到將'('彈出運算符棧 
                while (topOp.name != '(') 
                { 
                    pushNumber(operate(topOp)); 
                    topOp = popOperator(); 
                } 
            } 
            else 
            { 
                //如果是普通運算符 
                if (topOp.name != '#' && op.priority <= topOp.priority) 
                { 
                    //如果運算符棧非空,且當前運算符的優先級大於棧頂運算符,則進行一次運算,將結果壓入操作數棧 
                    pushNumber(operate(topOp)); 
                } 
                else 
                { 
                    //否則將從棧頂彈出的運算符壓回 
                    pushOperator(topOp); 
                } 
                //將當前運算符壓棧 
                pushOperator(op); 
            } 
            i++; 
        } 
    } 
    //完成棧內剩余的運算 
    while ((topOp = popOperator()).name != '#') 
    { 
        pushNumber(operate(topOp)); 
    } 
    //操作數棧中剩下的最後一個數即為結果 
    printf("%f\n", popNumber()); 
    return 0; 

 

作者:卞昊穹 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved