BUAA(2021春)表达式求值——巧妙利用数组完成

48 篇文章 154 订阅
本文介绍了如何解决数据结构课程中的表达式求值问题,涉及栈的应用和整数算术运算。通过两个不同的算法实现,包括基础的栈操作和搜索加减号进行分割计算,对整数算术表达式的处理进行了详细阐述。同时,补充测试数据和易错点分析有助于加深理解。
摘要由CSDN通过智能技术生成

看前须知

要点介绍和简要声明.

第一次上机题汇总

扩展字符A——strchr的灵活使用.

表达式求值.

小数形式与科学计数法转换(简)——分类讨论一定要有逻辑.

超长正整数的减法(高精度减法)+其他三种高精度运算.

全排列数的生成——DFS(深度优先遍历)+回溯 秒杀本题.

题目内容

问题描述

从标准输入中读入一个整数算术运算表达式,如5 - 1 * 2 * 3 + 12 / 2 / 2 = 。计算表达式结果,并输出。

要求:

  1. 表达式运算符只有+、-、*、/,表达式末尾的’=’字符表示表达式输入结束,表达式中可能会出现空格;

  2. 表达式中不含圆括号,不会出现错误的表达式;

  3. 出现除号/时,以整数相除进行运算,结果仍为整数,例如:5/3结果应为1。

输入形式

从键盘输入一个以=结尾的整数算术运算表达式。操作符和操作数之间可以有空格分隔。

输出形式

向控制台输出计算结果(为整数)。

样例

输入

5 - 1 * 2 * 3 + 12 / 2 / 2 =

输出

2

输入

500 =

输出

500

样例说明

【样例1说明】

输入的表达式为5 - 1 * 2 * 3 + 12 / 2 / 2 =,按照整数运算规则,计算结果为2,故输出2。

【样例2说明】

输入的表达式为500 = ,没有运算符参与运算,故直接输出500。

题解

易错点和难点

算法之一提示:
1、可以利用gets函数,读取整行表达式;
2、对于空格,可以考虑首先去除表达式中的所有空格
3、可以设一计数器用来记录已读取、但未参加运算的运算符的个数,根据该计数器来判断如何进行运算;
4、可以设计一函数:实现二元整数算术运算。

参考代码

1.栈(最最基础的,只有入栈)

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<ctype.h>
int calculate(char* s) {
    int n = strlen(s);
    int stk[n], top = 0;
    char preSign = '+';
    int num = 0;
    for (int i = 0; i < n; ++i) {
        if (isdigit(s[i])) {
            num = num * 10 + (int)(s[i] - '0');
        }
        if (!isdigit(s[i]) && s[i] != ' ' || i == n - 1) {
            switch (preSign) {
                case '+':
                    stk[top++] = num;
                    break;
                case '-':
                    stk[top++] = -num;
                    break;
                case '*':
                    stk[top - 1] *= num;
                    break;
                default:
                    stk[top - 1] /= num;
            }
            preSign = s[i];
            num = 0;
        }
    }
    int ret = 0;
    for (int i = 0; i < top; i++) {
        ret += stk[i];
    }
    return ret;
}

int main() 
{ 
	char s[2000];
	gets(s);
	s[strlen(s)-1]='\0';
	printf("%d\n",calculate(s)); 
	return 0; 
} 

2.搜寻加减号的位置,然后作为分割线,分别计算之间的乘除

#include<stdio.h>
#include<string.h>
char fh[10000];
int num[10000];
int cnt_fh=1;

int main(){
	fh[0]='+';
    int cnt_num=0;
    while(fh[cnt_fh-1]!='='){
    	scanf("%d",&num[cnt_num++]);
    	char tmp_c;
	    scanf("%c",&tmp_c);
    	while(tmp_c==' ') scanf("%c",&tmp_c);
	    fh[cnt_fh++]=tmp_c;
	}
	//数据读取完毕;
	int cnt_jj=0;
	int position_jj[1000];
	int i;
	for(i=0;i<cnt_fh;i++){
		if(fh[i]=='+'||fh[i]=='-') position_jj[cnt_jj++]=i;
	}
	position_jj[cnt_jj]=cnt_fh-1;
	//加减号定位完毕;
	int sum=0;
	int h;
	for(h=0;h<cnt_jj;h++){//处理第h个加减号后的乘除法 
		int a;
		a=num[position_jj[h]];
		for(i=position_jj[h]+1;i<position_jj[h+1];i++){
			if(fh[i]=='*') a*=num[i];
			else if(fh[i]=='/') a/=num[i];
		}
		if(fh[position_jj[h]]=='+') sum+=a;
		else if(fh[position_jj[h]]=='-') sum-=a;
	} 
	printf("%d",sum);

}

补充测试的数据

没有特别注意的地方.

题单链接

有考虑过负数和乘方怎么解决吗好兄弟

负数.
乘方.

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值