【C/C++】含括號的四則運算(棧方式實現)

 使用棧來實現含括號的四則運算,複雜的就是各種分支的判斷,當時參考了很多前輩的代碼,又自己敲了很久,得到一個最終版,在此記錄一下,希望若干年後的自己看到時能夠不忘初心。

#include<stdio.h>
#include<stdlib.h>


/*數據棧*/
struct shuju {
    float data[100];
    int top;
};


/*符號棧*/ 
struct fuhao {
    char symbol[100];
    int top;
};


void InitOperateNum(struct shuju *StackNum)  
{
    StackNum->top = -1;
}


void InitOperateSymbol(struct fuhao *StackSymbol)  
{  
    StackSymbol->top = -1; 
}


/*存入數據棧*/
void Inshuju(struct shuju *StackNum, int num)
{
    StackNum->top ++;
    StackNum->data[StackNum->top] = num;
}


/*存入符號棧*/ 
void Infuhao(struct fuhao *StackSymbol, char ch)
{
    StackSymbol->top ++;
    StackSymbol->symbol[StackSymbol->top] = ch;
}


/*讀取數據棧*/
int Readshuju(struct shuju *StackNum)
{
    return StackNum->data[StackNum->top];
}


/*讀取符號棧*/
char Readfuhao(struct fuhao *StackSymbol)
{
    return StackSymbol->symbol[StackSymbol->top];
}


/*從數據棧取出數據*/
int Putshuju(struct shuju *StackNum)
{
    int x;
    x = StackNum->data[StackNum->top];
    StackNum->top --;
    return x;
}


/*從符號棧取出符號*/
char Putfuhao(struct fuhao *StackSymbol)
{
    char c;
    c = StackSymbol->symbol[StackSymbol->top];
    StackSymbol->top --;
    return c;
}


/*符號優先級判斷*/
int judge(char ch) {
    if(ch == '(') {
        return 1; 
    }
    if(ch == '+' || ch == '-') {
        return 2;
    }
    else if(ch == '*' || ch == '/') {
        return 3;
    }
    else if(ch == ')') {
        return 4;
    }
}


/*四則運算*/
int Math(float v1, float v2, char c)
{
    float sum;
    switch(c) {
        case '+' : {
            sum = v1 + v2;
            break;
        }
        case '-' : {
            sum = v1 - v2;
            break;
        }
        case '*' : {
            sum = v1 * v2;
            break;
        } 
        case '/' : {
            sum = v1 / v2;
            break;
        }
    }
    return sum;
}

void manu(){
	printf("**********************************************************\n");
	printf("\t算術運算菜單\n");
	printf("1、加法運算\n");
	printf("2、減法運算\n");
	printf("3、乘法運算\n");
	printf("4、除法運算\n");
	printf("5、混合運算(無括號)\n");
	printf("6、混合運算(有括號)\n");
	printf("0、輸入0退出程序\n");
	printf("**********************************************************\n");
}

int main()
{
    while(1){
    	manu();
    	printf("請輸入表達式:");
    	struct shuju data;
	    struct fuhao symbol;
	    InitOperateNum(&data);
	    InitOperateSymbol(&symbol);
	    int i, t;
		float v1, v2;
	    float sum;
	    char c;
	    i = t =  0;
	    sum =0;
	    char v[100] = {0};
	    char *str = (char *)malloc(sizeof(char)*200);
	    while((c = getchar()) != '\n') {
	        str[i] = c;
	        i ++;
	    }
	    str[i] = '\0';
	    for(i = 0; str[i] != '\0'; i ++) {
	        if(i == 0 && str[i] == '-') {
	            v[t++] = str[i];
	        }
	        else if(str[i] == '(' && str[i+1] == '-') {
	            i ++;
	            v[t++] = str[i++];
	            while(str[i] >= '0' && str[i] <= '9') {
	                v[t] = str[i];
	                t ++;
	                i ++;
	            }
	            Inshuju(&data, atoi(v));
	            while(t > 0) {
	                v[t] = 0;
	                t --;
	            }
	            if(str[i] != ')') {
	                i --;
	                Infuhao(&symbol, '(');
	            }
	        }
	        else if(str[i] >= '0' && str[i] <= '9') {
	            while(str[i] >= '0' && str[i] <= '9') {
	                v[t] = str[i];
	                t ++;
	                i ++;
	            }
	            Inshuju(&data, atoi(v));
	            while(t > 0) {
	                v[t] = 0;
	                t --;
	            }
	            i --;
	        }
	        else {
	            if(symbol.top == -1) {        //如果符號棧沒有元素,直接把符號放入符號棧 
	                Infuhao(&symbol, str[i]);
	            }
	            else if(judge(str[i]) == 1) { //如果此符號是'(',直接放入符號棧 
	                Infuhao(&symbol, str[i]);
	            }
	            else if(judge(str[i]) == 2) { //如果此符號是'+'或'-',判斷與棧頂符號是優先級 
	                if(judge(Readfuhao(&symbol)) == 1) { //如果棧頂符號是'(',放入符號棧 
	                    Infuhao(&symbol, str[i]);
	                }
	                else if(judge(Readfuhao(&symbol)) == 2) { //如果棧頂符號是'+'或'-',則出棧運算 
	                    while(symbol.top >= 0 && data.top >= 1) { //循環出棧
	                        v2 = Putshuju(&data);
	                        v1 = Putshuju(&data);
	                        sum = Math(v1, v2, Putfuhao(&symbol));
	                        Inshuju(&data, sum); //將運算結果壓入數據棧 
	                    }
	                    Infuhao(&symbol, str[i]); //新符號進棧 
	                }
	                else if(judge(Readfuhao(&symbol)) == 3) { //如果棧頂符號是'*'或'/',則進符號棧 
	                    while(symbol.top >= 0 && data.top >= 1) { //循環出棧
	                        v2 = Putshuju(&data);
	                        v1 = Putshuju(&data);
	                        sum = Math(v1, v2, Putfuhao(&symbol));
	                        Inshuju(&data, sum); //將運算結果壓入數據棧 
	                    }
	                    Infuhao(&symbol, str[i]); //新符號進棧 
	                }
	                /*棧頂符號不可能是')',故不做判斷*/ 
	            }
	            else if(judge(str[i]) == 3) { //如果此符號是'*'或'/',則判斷與棧頂符號是優先級
	                if(judge(Readfuhao(&symbol)) == 1) { //如果棧頂符號是'(',放入符號棧 
	                    Infuhao(&symbol, str[i]);
	                }
	                else if(judge(Readfuhao(&symbol)) == 2) { //如果棧頂符號是'+'或'-',則進符號棧
	                    Infuhao(&symbol, str[i]); //新符號進棧
	                }
	                else if(judge(Readfuhao(&symbol)) == 3) { //如果棧頂符號是'*'或'/',則出棧運算 
	                    while(symbol.top >= 0 && data.top >= 1) { //循環出棧
	                        v2 = Putshuju(&data);
	                        v1 = Putshuju(&data);
	                        sum = Math(v1, v2, Putfuhao(&symbol));
	                        Inshuju(&data, sum); //將運算結果壓入數據棧 
	                    }
	                    Infuhao(&symbol, str[i]); //新符號進棧
	                }
	            }
	            else if(judge(str[i]) == 4) { // 如果棧頂符號是')',則出棧運算直到遇到'('
	                do { //循環出棧直到遇到'('
	                    v2 = Putshuju(&data);
	                    v1 = Putshuju(&data);
	                    sum = Math(v1, v2, Putfuhao(&symbol));
	                    Inshuju(&data, sum); //將運算結果壓入數據棧 
	                }while(judge(Readfuhao(&symbol)) != 1);
	                Putfuhao(&symbol); //括號內運算結束後使'('出棧 
	            }       
	        }
	    }
	    free(str); //釋放內存空間
	    while(symbol.top != -1) {
	        v2 = Putshuju(&data);
	        v1 = Putshuju(&data);
	        sum = Math(v1, v2, Putfuhao(&symbol));
	        Inshuju(&data, sum);    
	    }
    printf("%.2f\n", data.data[0]);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章