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

算符优先法图

代码还添加了乘方的优先级,自行参考
一开始我写的只能输入个位数,后来想了好久才解决,主要是在判断是否为运算符后,若不是运算符,别急着入栈,用一个标记数组记着,若下一个字符还不是运算符,则利用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;

}
  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值