C语言算术表达式求值

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <math.h>

#define MAX_LENTH 30

#define  MAX 100

typedef struct

{

    int data[MAX_LENTH];

    int top;

} Stack;

Stack *Createstack()

{

    Stack *p;

    p = (Stack *)malloc(sizeof(*p));

    p->top = -1;

    return p;

}

int Push(Stack *p,int x)

{

    if (p->top == MAX_LENTH - 1)

    {

        return -1;

    }

    p->top++;

    p->data[p->top] = x;

    return 0;

}

int Pop(Stack *L,int *x)

{

    if (L->top == -1)

    {

        return -1;

    }

    *x = L->data[L->top];

    L->top--;

    return 0;

}

int TOP(Stack *L,int *x)

{

    if (L->top == -1)

    {

        return -1;

    }

    *x = L->data[L->top];

    return 0;

}

int Empty(Stack *L)

{

    return (L->top == -1);

}

int Priority(int ope)

{

    switch(ope)

    {

    case '(':

        return 0;

    case '+':

    case '-':

        return 1;

    case '*':

    case '/':

        return 2;

    default :

        return -1;

    }

}

void Calculation(Stack *snum,int ope)

{

    int n,n1,n2;

    Pop(snum,&n1);

    Pop(snum,&n2);

    switch(ope)

    {

    case '+':

        n = n1 + n2;

        break;

    case '-':

        n = n2 - n1;

        break;

    case '*':

        n = n1 * n2;

        break;

    case '/':

        n = n2 / n1;

        break;

    }

    Push(snum,n);

}

//初始sope栈空 遵守规则4-a 运算符直接入栈

//规则2 左括号入栈

//规则4 old_ope是栈顶运算符

//规则4-a Priority(ope) > Priority(old_ope

//规则4-b Priority(ope) <= Priority(old_ope

//规则4-b-1 栈顶运算符弹出并打印, 调用Calculation(snum,old_ope)结果入snum栈

//规则4-b-2准备下一次用于比较的新的栈顶运算符

//规则4-b-3 运算符压栈

void Deal_ope(Stack *snum,Stack *sope,int ope)

{

    int old_ope;

                    //初始sope栈空 遵守规则4-a 运算符直接入栈

    if (ope == ')') {

    while(!Empty(sope) && old_ope != '(') {

        Pop(sope,&old_ope);

        Push(snum,old_ope);

        TOP(sope,&old_ope);

    }

    if(old_ope == '(') {

        Pop(sope,&old_ope);//剔除左括号

    }

    return ;

}

while(!Empty(sope) && old_ope != '(' && Priority(ope) <= Priority(old_ope))

{

    Pop(sope,&old_ope);

    Push(snum,old_ope);

    TOP(sope,&old_ope);//规则4-b-2准备下一次用于比较的新的栈顶运算符

}

Push(sope,ope);

}

//此此函数是规则3  遇到右括号

//规则3-a sope栈顶的运算符弹出并打印

//并调用Calculation(snum,old_ope)结果入snum栈 直到遇到左括号

//规则3-b 出栈左括号

void Right(Stack *snum,Stack *sope)

{

int old_ope;

TOP(sope,&old_ope);

while (old_ope != '(') //规则3-a直到遇到左括号

{

Pop(sope,&old_ope);

printf("%c ",old_ope);

Calculation(snum,old_ope);

TOP(sope,&old_ope);

}

Pop(sope,&old_ope); //规则3-b弹出左括号

}

int Display(Stack *L)

{

    int i;

    if (L->top == -1)

    {

        return 0 ;

    }

    for (i=0; i<=L->top; i++)

    {

        printf("%d ",L->data[i]);

    }

    printf("\n");

    return 0;

}

void Displayope(Stack *L)

{

    int i;

    if (L->top == -1)

    {

        return ;

    }

    for (i=0; i<=L->top; i++)

    {

        printf("%c ",L->data[i]);

    }

    printf("\n");

}

//此函数是判断输入字符是否符合四则运算式定义

int func(char a[])

{

    int i=0,d1=0,d2=0;

    char b[1005];

    char c[1005];

    while(a[i]!='\0')

    {

        if ((a[i]>=48&&a[i]<=57)||a[i]=='('||a[i]==')'||a[i]=='+'||a[i]=='-'||a[i] =='*'||a[i]=='/')

        {

        }

        else

        {

            printf("含有非法字符\n");

            return 0;

        }

        if(a[i]=='(')

        {

            b[d1]=a[i];

            d1++;

        }

        else if(a[i]==')')

        {

            c[d2]=a[i];

            d2++;

        }

        if(a[i]=='/'&&a[i+1]=='0')

        {

            printf("除数不得为0\n");

            return 0;

        }

        else if(a[i]=='('&&a[i+1]==')')

        {

            printf("括号内为空\n");

            return 0;

        }

        else if (a[i]=='('&&a[i-1]>=48&&a[i-1]<=57)   {printf("表达式错误\n");return 0;}

            else if (a[i]==')'&&a[i+1]>=48&&a[i+1]<=57) {

                    printf("表达式错误%d\n",a[i+1]);

                    return 0;

                }

        i++;

    }

    if(d1==d2)

    {

        return 1;

    }

    else

    {

        printf("括号不匹配\n");

        return 0;

    }

}

int main()

{

    int ffs;

    char str[MAX],dst[MAX];

    printf("(请使用英文输入法,表达式不用加等号)\n");

    printf("中缀表达式为:");

    scanf("%s",str);

    ffs=func(str);

    if(ffs==0)

    {

        printf("error!\n");

        return 0;

    }

    else

    {

        printf("%s合法\n",str);

    }

    int i = 0,value = 0,flag = 0;

    int old_ope;

    Stack *numstack,*opestack;

    numstack = Createstack();

    opestack = Createstack();

    printf("后缀表达式为:");

    //处理多位数字字符 flag为1时表明多位数字值为value

    while (str[i] != '\0')

    {

        if (str[i] >= '0' && str[i] <= '9')

        {

            value *= 10;

            value +=str[i]-'0';

            flag = 1;

        }

        else

        {

            if (flag)

            {

                printf("%d ",value);

                Push (numstack, value);

                flag = 0;//flag标示数字已入栈

                value = 0;

            }

            if(str[i] == ')') Right(numstack,opestack);

            else Deal_ope(numstack,opestack,str[i]);

        }

        i++;

    }

    if (flag)//flag=1 标示数字已经处理妥当 可以打印输出

    {

        printf("%d ",value);Push(numstack,value);

    }

    while (!Empty(opestack))     //规则5

    {

        Pop(opestack,&old_ope);

        printf("%c ",old_ope);

        Calculation(numstack,old_ope);

    }

    Pop(numstack,&value);

    printf("\n%s = %d\n",str,value);

    return 0;

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,您可以这样写一个基于栈的中缀表达式求值程序: ```c #include <stdio.h> #include <stdlib.h> #include <ctype.h> #define MAX_SIZE 50 typedef int ElemType; typedef struct { ElemType data[MAX_SIZE]; int top; } Stack; void push(Stack *s, ElemType e) { if (s->top == MAX_SIZE) { printf("stack overflow\n"); exit(1); } s->data[s->top++] = e; } ElemType pop(Stack *s) { if (s->top == 0) { printf("stack underflow\n"); exit(1); } return s->data[--s->top]; } ElemType peek(Stack *s) { if (s->top == 0) { printf("stack empty\n"); exit(1); } return s->data[s->top - 1]; } int is_op(char c) { return c == '+' || c == '-' || c == '*' || c == '/'; } int cmp_op(char op1, char op2) { if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) return 1; return 0; } int eval(char op, int b, int a) { switch (op) { case '+': return a + b; case '-': return a - b; case '*': return a * b; case '/': return a / b; } return 0; } int eval_expr(char *expr) { Stack op_stack, num_stack; op_stack.top = 0; num_stack.top = 0; int i = 0; while (expr[i] != '\0') { if (isdigit(expr[i])) { int num = 0; while (isdigit(expr[i])) { num = num * 10 + (expr[i] - '0'); i++; } push(&num_stack, num); } else if (is_op(expr[i])) { while (op_stack.top > 0 && !cmp_op(expr[i], peek(&op_stack))) { int b = pop(&num_stack); int a = pop(&num_stack); char op = pop(&op_stack); int result = eval(op, b, a); push(&num_stack, result); } push(&op_stack, expr[i]); i++; } else if (expr[i] == '(') { push(&op_stack, '('); i++; } else if (expr[i] == ')') { while (peek(&op_stack) != '(') { int b = pop(&num_stack); int a = pop(&num_stack); char op = pop(&op_stack); int result = eval(op, b, a); push(&num_stack, result); } pop(&op_stack); i++; } else { i++; } } while (op_stack.top > 0) { int b = pop(&num_stack); int a = pop(&num_stack); char op = pop(&op_stack); int result = eval(op, b, a); push(&num_stack, result); } return pop(&num_stack); } int main(void) { char expr[MAX_SIZE]; printf("Enter an infix expression: "); scanf("%s", expr); int result = eval_expr(expr); printf("Result: %d\n", result); return 0; } ``` 该程序使用两个栈来实现中缀表达式求值,一个保存操作数,一个保存操作符。遍历表达式的每个字符,如果是数字,则从当前位置开始解析数字,并将其压入操作数栈中;如果是操作符,则依次将栈顶符号与当前符号比较优先级,如果栈顶符号优先级较高,则弹出两个操作数和一个操作符,计算出结果并将其压入操作数栈中,否则将当前符号压入操作符栈中;如果是左括号,则直接将其压入操作符栈中;如果是右括号,则依次弹出操作数栈和操作符栈中的元素,直到遇到左括号为止,并将计算结果压入操作数栈中;其他字符则忽略。最后,当操作符栈不为空时,依次弹出操作数栈和操作符栈中的元素,计算出最终结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LMX---2015

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值