用栈做一个简单的计算器(表达式的计算)

本文介绍了一种使用栈数据结构解决复杂表达式计算问题的方法,包括操作数栈和运算符栈的设计,以及如何处理整数、小数和运算符的优先级比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用栈解决表达式的计算问题
1.首先要有两个栈一个操作数栈一个运算符栈;
2.设置表达式的结束符是#,预设运算符
3.若当前字符是操作数,则直接压入操作数栈
4.若当前字符是运算符,且运算符的优先级高于栈顶运算符则进栈,否则从操作数栈中弹出两个操作数并弹出运算符栈的栈顶运算符,经计算后,将结果压入操作数栈。

//操作数栈
typedef struct{
float an[20];
int topn;
}OPRD;

//运算符栈
typedef struct{
char ac[20];
int topc;
}OPTR;

在做的过程中有以下几个问题吧:
问题一:如何把输入的字符转化为浮点型

 wb = wb + ((float)love[i-n]-48) * (power(10,n-1));

用到了一个类型转化符,里面的power()函数是一个求指数的函数;具体代码如下:

//求指数
int power(int a , int b)
{
        int i=0;
        int wb=1;
        for(;i<b;i++)
                wb *= a;
        return wb;
}

问题二:如果输入的是‘2’‘1’,怎么让他读入21;

n=0
if(love[i]>='0' && love[i]<='9')
                {
                        while(love[i]>='0' && love[i]<='9')
                        {
                                n++;
                                i++;
                        }
                        while(n!=0)
                        {
                                wb = wb + ((float)love[i-n]-48) * (power(10,n-1));
                                n--;
                        }
                }

问题三:如果是小数怎么办

 if(love[i] == '.')
                        {
                                i++;
                                while(love[i]>='0' && love[i]<='9')
                                {
                                        n++;
                                        i++;
                                }
                                while(n!=0)
                                {
                                        wb = wb + ((float)love[i-n]-48) / (power(10,n));
                                        n--;
                                }
                        }

问题四:运算符的比较
就是用switch函数对两个运算符进行比较通过返回值判断大小具体函数在下面;

下面放完整代码

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

//操作数栈
typedef struct{
float an[20];
int topn;
}OPRD;

//运算符栈
typedef struct{
char ac[20];
int topc;
}OPTR;

//字符串输入函数
char *s_gets(char  *a , int n)
{
        char *b;
        int i=0;
        b= fgets(a,n,stdin);
        if(b)
        {
                while(a[i]!='\n' && a[i]!='\0')
                        i++;
                if(a[i]=='\n')
                        a[i]='\0';
                else
                        while(getchar()!='\n')
                                continue;
        }
        return b;
}

//求指数
int power(int a , int b)
{
        int i=0;
        int wb=1;
        for(;i<b;i++)
                wb *= a;
        return wb;
}

//操作数入栈函数
int push_n(OPRD *s , float x)
{
        if(s->topn == 19)
                return 0;
        else
                s->an[++s->topn] = x;
        return 1;
}

//运算符的比较
int bijiao(char a , char b)
{
        switch(a)
        {
                case '+':
                        {
                                switch(b)
                                {
                                        case '+':return 0;
                                        case '-':return 0;
                                        case '*':return 1;
                                        case '/':return 1;
                                        case '(':return 1;
                                        case ')':return 0;
                                        case '#':return 0;
                                        default:break;
                                }
                        }
                case '-':
                        {
                                switch(b)
                                {
                                        case '+':return 0;
                                        case '-':return 0;
                                        case '*':return 1;
                                        case '/':return 1;
                                        case '(':return 1;
                                        case ')':return 0;
                                        case '#':return 0;
                                        default:break;
                                }
                        }
                case '*':
                        {
                                switch(b)
                                {
                                        case '+':return 0;
                                        case '-':return 0;
                                        case '*':return 0;
                                        case '/':return 0;
                                        case '(':return 1;
                                        case ')':return 0;
                                        case '#':return 0;
                                        default:break;
                                }

                        }
                case '/':
                        {
                                switch(b)
                                {
                             case '+':return 0;
                                        case '-':return 0;
                                        case '*':return 0;
                                        case '/':return 0;
                                        case '(':return 1;
                                        case ')':return 0;
                                        case '#':return 0;
                                        default:break;
                                }

                        }
                case '(':
                        {
                                switch(b)
                                {
                                        case '+':return 1;
                                        case '-':return 1;
                                        case '*':return 1;
                                        case '/':return 1;
                                        case '(':return 1;
                                        default:break;
                                }

                        }
                case ')':
                        {
                                switch(b)
                                {
                                        case '+':return 0;
                                        case '-':return 0;
                                        case '*':return 0;
                                        case '/':return 0;
                                        case ')':return 0;
                                        case '(':return 2;
                                        case '#':return 0;
                                        default:break;
                                }

                        }
                case '#':
                        {
                                switch(b)
                                {
                                        case '+':return 1;
                                        case '-':return 1;
                                        case '*':return 1;
                                        case '/':return 1;
                                        case '(':return 1;
                                        case '#':return 2;
                                        default:break;
                                }

                        }
        }
}

//操作数出栈
int popn(OPRD *s , float *x)
{
        if(s->topn == -1)
                return 0;
        else
                *x = s->an[s->topn--];
        return 1;
}

//运算符出栈
int popc(OPTR *s , char *x)
{
        if(s->topc == -1)
                return 0;
        else
                *x = s->ac[s->topc--];
        return 1;
}

//判断运算符栈空
int kong_c(OPTR *s)
{
        if(s->topc == -1)
                return 0;
        else
                return 1;
}

int main()
{
        OPTR *s;
        OPRD *p;
        int k,i,n;
        i=0;
        n=0;
        float wb=0;
        char ch;
        char love[40];
        float a,b;
        s = (OPTR*)malloc(sizeof(OPTR));
        p = (OPRD*)malloc(sizeof(OPRD));
        s->topc = -1;
        printf("%d",s->topc);
        p->topn = -1;
        printf("输入以#开头以#结尾的表达式:\n");
        s_gets(love,40);
        k = strlen(love);
        for(;i<k;)
        {
                wb=0;
                if(love[i]>='0' && love[i]<='9')
 {
                        while(love[i]>='0' && love[i]<='9')
                        {
                                n++;
                                i++;
                        }
                        while(n!=0)
                        {
                                wb = wb + ((float)love[i-n]-48) * (power(10,n-1));
                                n--;
                        }
                        if(love[i] == '.')
                        {
                                i++;
                                while(love[i]>='0' && love[i]<='9')
                                {
                                        n++;
                                        i++;
                                }
                                while(n!=0)
                                {
                                        wb = wb + ((float)love[i-n]-48) / (power(10,n));
                                        n--;
                                }
                        }
                        push_n(p,wb);
                }
                else
                {
                        if(kong_c(s) == 0 || love[i]=='(')
                        {
                                push_c(s,love[i]);
                                i++;
                        }
                        else
                        {
                                getac(s,&ch);
                                while(bijiao(ch,love[i])!=1 && bijiao(ch,love[i])!=2)
                                {
                                        popc(s,&ch);
                                        popn(p,&a);
                                        popn(p,&b);
                                        switch(ch)
                                        {
                                                case '+':wb = b + a;break;
                                                case '-':wb = b - a;break;
                                                case '*':wb = b * a;break;
                                                case '/':wb = b / a;break;
                                                case ')':break;
                                                default:break;
                                        }
                                        push_n(p,wb);
                                        getac(s,&ch);
                                }
 if(bijiao(ch,love[i])==2)
                                {
                                        popc(s,&ch);
                                        i++;
                                }
                                else if(bijiao(ch,love[i])==1)
                                {
                                        push_c(s,love[i]);
                                        i++;
                                }
                        }
                }

        }
        popn(p,&wb);
        printf("结果是%.2f\n",wb);
}

好的,下面是一个实现的表达式计算器,它支持加、减、乘、除、括号等基本运算符和功能: ```c #include <stdio.h> #include <stdlib.h> #include <ctype.h> // 定义结构 struct stack { int *data; int top; int size; }; // 创建 struct stack *create_stack(int size) { struct stack *s = (struct stack*)malloc(sizeof(struct stack)); s->data = (int*)malloc(size * sizeof(int)); s->top = -1; s->size = size; return s; } // 销毁 void destroy_stack(struct stack *s) { if (s != NULL) { free(s->data); free(s); } } // 入 void push(struct stack *s, int val) { if (s->top < s->size - 1) { s->top++; s->data[s->top] = val; } } // 出 int pop(struct stack *s) { if (s->top >= 0) { int val = s->data[s->top]; s->top--; return val; } return 0; } // 获取顶元素 int top(struct stack *s) { if (s->top >= 0) { return s->data[s->top]; } return 0; } // 判断是否为空 int is_empty(struct stack *s) { return s->top < 0; } // 解析数字 int parse_number(char *expr, int *index) { int val = 0; while (isdigit(expr[*index])) { val = val * 10 + (expr[*index] - '0'); (*index)++; } return val; } // 计算表达式 int eval_expr(char *expr) { struct stack *nums = create_stack(100); struct stack *ops = create_stack(100); int index = 0; while (expr[index] != '\0') { if (isdigit(expr[index])) { int val = parse_number(expr, &index); push(nums, val); } else if (expr[index] == '(') { push(ops, '('); index++; } else if (expr[index] == '+' || expr[index] == '-') { while (!is_empty(ops) && top(ops) != '(') { int val2 = pop(nums); int val1 = pop(nums); int op = pop(ops); if (op == '+') { push(nums, val1 + val2); } else if (op == '-') { push(nums, val1 - val2); } } push(ops, expr[index]); index++; } else if (expr[index] == '*' || expr[index] == '/') { while (!is_empty(ops) && (top(ops) == '*' || top(ops) == '/')) { int val2 = pop(nums); int val1 = pop(nums); int op = pop(ops); if (op == '*') { push(nums, val1 * val2); } else if (op == '/') { push(nums, val1 / val2); } } push(ops, expr[index]); index++; } else if (expr[index] == ')') { while (!is_empty(ops) && top(ops) != '(') { int val2 = pop(nums); int val1 = pop(nums); int op = pop(ops); if (op == '+') { push(nums, val1 + val2); } else if (op == '-') { push(nums, val1 - val2); } else if (op == '*') { push(nums, val1 * val2); } else if (op == '/') { push(nums, val1 / val2); } } pop(ops); index++; } else { index++; } } while (!is_empty(ops)) { int val2 = pop(nums); int val1 = pop(nums); int op = pop(ops); if (op == '+') { push(nums, val1 + val2); } else if (op == '-') { push(nums, val1 - val2); } else if (op == '*') { push(nums, val1 * val2); } else if (op == '/') { push(nums, val1 / val2); } } int result = top(nums); destroy_stack(nums); destroy_stack(ops); return result; } // 主函数 int main() { char expr[100]; printf("请输入表达式:"); scanf("%s", expr); int result = eval_expr(expr); printf("表达式的值为:%d\n", result); return 0; } ``` 您可以将以上代码保存为一个.c文件并编译运行,输入表达式后即可计算表达式的值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值