数据结构-算术表达式-算符优先法

来源:互联网 发布:网络弊大于利尖锐问题 编辑:程序博客网 时间:2024/04/30 03:49

算符优先法图

代码还添加了乘方的优先级,自行参考
一开始我写的只能输入个位数,后来想了好久才解决,主要是在判断是否为运算符后,若不是运算符,别急着入栈,用一个标记数组记着,若下一个字符还不是运算符,则利用strcat函数链接之前标记数组和这一个字符,直到下一个字符是运算符为止,才入栈。

至于负数的运算,则要判断是否连续两个都为运算符,且前一个运算符为‘(’后一个运算符为‘-’,若是就加个0入栈即可。

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#define M 10#define add 10/*字符栈*/typedef struct{        char *base;        int stacksize;        int top;} sqstack;int init(sqstack &s){        s.base = (char *)malloc(M * sizeof(char));        if (!s.base)        {                exit(-1);        }        s.top = 0;        s.stacksize = M;        return 1;}int push(sqstack &s, char e){        char *newbase;        if (s.top == s.stacksize)        {                newbase = (char *)realloc(s.base, (s.stacksize + add) * sizeof(char));                if (!newbase)                {                        exit(-1);                }                s.base = newbase;                s.stacksize += add;        }        s.base[s.top++] = e;        return 1;}int pop(sqstack &s, char &e){        if (!s.top)        {                exit(-1);        }        e = s.base[--s.top];        return 1;}int Gettop(sqstack s, char &e){        if (!s.top)        {                exit(-1);        }        e = s.base[s.top - 1];        return 1;}/*操作数栈*/typedef struct{        float *base;        int top;        int stacksize;} datastack;int init_data(datastack &s){        s.base = (float *)malloc(M * sizeof(float));        if (!s.base)        {                exit(-1);        }        s.top = 0;        s.stacksize = M;        return 1;}int push_data(datastack &s, float e){        float *newbase;        if (s.top == s.stacksize)        {                newbase = (float *)realloc(s.base, (s.stacksize + add) * sizeof(float));                if (!newbase)                {                        exit(-1);                }                s.base = newbase;                s.stacksize += add;        }        s.base[s.top++] = e;        return 1;}int pop_data(datastack &s, float &e){        if (!s.top)        {                exit(-1);        }        e = s.base[--s.top];        return 1;}int gettop_data(datastack s, float &e){        if (!s.top)        {                exit(-1);        }        e = s.base[s.top - 1];        return 1;}/*判断算符优先关系*/char judge(char a, char b){        switch (a)        {        case '+':                if (b == '+' || b == '-' || b == ')' || b == '#')                {                        return '>';                }                else                {                        return '<';                }        case '-':                if (b == '+' || b == '-' || b == ')' || b == '#')                {                        return '>';                }                else                {                        return '<';                }        case '*':                if (b == '(' || b == '^')                {                        return '<';                }                else                {                        return '>';                }        case '/':                if (b == '(' || b == '^')                {                        return '<';                }                else                {                        return '>';                }        case '#':                if (b == '#')                {                        return '=';                }                else if (b == ')')                {                        return ' ';        /*返回空值,为后面判断与'=''>''<'区分*/                }                else                {                        return '<';                }        case '(':                if (b == ')')                {                        return '=';                }                else if (b == '#')                {                        return ' ';                }                else                {                        return '<';                }        case ')':                if (b == '(')                {                        return ' ';                }                else                {                        return '>';                }        case '^':                if (b == '(')                {                        return '<';                }                else                {                        return '>';                }        default:                return ' ';        }}/*计算操作*/float action(float a, char k, float b){        switch (k)        {        case '+':                return a + b;        case '-':                return a - b;        case '*':                return a * b;        case '/':                return a / b;        case '^':                return pow(a, b);        default :                return 0.0;        }}/*判断运算符or操作数*/int isysf(char c){        if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')' || c == '#' || c == '^')        {                return 1;        }        return 0;}/*正片*/float hehe(char *input){        sqstack optr;        datastack opnd;        float a, b, data, ku = 0;        int i = 0;        float ans;        int flag = 0; /*用作判断是否为负数*/        char e, x, y;        char tempdata[20], ap[2] = {'#', '\0'};        char *c;        init(optr);        init_data(opnd);        push(optr, '#');        c = strcat(input, ap);        strcpy(tempdata, "\0");        Gettop(optr, e);        while (c[i] != '#' || e != '#')        {                if (!isysf(c[i]))                {                        ap[0] = c[i];                        strcat(tempdata, ap);                        i++;                        if (isysf(c[i]))                        {                                data = atof(tempdata);                                push_data(opnd, data);                                strcpy(tempdata, "\0");                        }                        flag = 0;                }                else                {                        if (flag) /*若连续两个都是运算符*/                        {                                Gettop(optr, y);                                if (y == '(' && c[i] == '-') /*判断输入是否为负数*/                                {                                        push_data(opnd, ku);  /*0入操作数栈*/                                        push(optr, c[i]);                                        i++;                                }                                else /*连续两个都是运算符却不是负数*/                                {                                        switch (judge(e, c[i]))                                        {                                        case '<':                                                push(optr, c[i]);                                                i++;                                                break;                                        case '=':                                                pop(optr, x);                                                i++;                                                break;                                        case '>':                                                pop(optr, e);                                                pop_data(opnd, a);                                                pop_data(opnd, b);                                                push_data(opnd, action(b, e, a));                                                break;                                        }                                }                        }                        else                        {                                switch (judge(e, c[i]))                                {                                case '<':                                        push(optr, c[i]);                                        i++;                                        break;                                case '=':                                        pop(optr, x);                                        i++;                                        break;                                case '>':                                        pop(optr, e);                                        pop_data(opnd, a);                                        pop_data(opnd, b);                                        push_data(opnd, action(b, e, a));                                        break;                                }                        }                        flag = 1;                }                Gettop(optr, e);        }        gettop_data(opnd, ans);        return ans;}int main(){        float a;        char c[1111];        printf("****************************************************************\n");        printf("\n加法:+   减法:-   乘法:*    除法:/   乘方:^  \n");        printf("\n数值可为任意实数,输入负数必须用括号()括起来,结果保留2位小数\n\n");        printf("****************************************************************\n\n");        while (1)        {                printf("输入表达式:\n");                gets(c);                a = hehe(c);                printf("表达式的值为:%.2f\n", a);        }        return 0;}
0 0