【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;
}
发布了31 篇原创文章 · 获赞 6 · 访问量 4180

猜你喜欢

转载自blog.csdn.net/zhenliangit0918/article/details/104290852