用两种方式实现表达式自动计算
WPSOffice如何在电子中使用函数进行自动计算
WPSOffice如何在电子中使用函数进行自动计算WPS Office如何在电子表格中使用函数进行自动计算WPS Office已经成为了许多用户首选的办公软件之一,其中电子表格功能十分强大。
在电子表格中,我们需要进行大量的计算和分析工作,而WPS Office提供了丰富的函数来帮助我们自动计算数据。
本文将介绍如何利用WPS Office中的函数来进行自动计算。
一、函数的基本概念和使用方法在WPS Office的电子表格中,函数是一种可以对数据进行计算、分析和处理的工具。
函数由一个函数名和一组参数组成,函数名用于指定要执行的特定计算操作,参数则是函数需要的输入数据。
使用函数前,我们需要了解函数的基本概念和使用方法。
1. 函数的语法:函数通常以等号“=”开头,后面是函数名称,接着是左括号“(”,然后是函数的参数,参数之间用逗号“,”分隔,最后以右括号“)”结尾。
例如,求和函数的语法为“=SUM(参数1,参数2,...)”。
2. 函数的参数:函数通常需要接受一些参数进行计算。
参数可以是单元格、数值、常量或其他的函数。
在填写参数时,我们可以直接输入对应的数值,也可以点击单元格引用进入。
多个参数之间用逗号分隔。
3. 自动计算:WPS Office会自动根据我们输入的函数和参数进行计算,并在单元格中显示计算结果。
当参数发生改变时,计算结果也会自动更新。
二、常用的函数及其用法WPS Office提供了各种常用函数,涵盖了基本的数学、逻辑、文本、日期等计算操作。
接下来,我们将介绍一些常用的函数及其用法。
1. SUM函数:用于求和SUM函数可以将多个参数相加,并返回它们的求和结果。
例如,要计算A1单元格和A2单元格的和,可以使用“=SUM(A1,A2)”。
2. AVERAGE函数:用于求平均值AVERAGE函数可以计算一组数值的平均值。
例如,要计算A1到A10的平均值,可以使用“=AVERAGE(A1:A10)”。
用两种方法实现表达式求值
一、设计思想一.中缀式计算结果的设计思想:此种算法最主要是用了两个栈:用两个栈来实现算符优先,一个栈用来保存需要计算的数据numStack(操作数栈),一个用来保存计算优先符priStack(操作符栈)。
从字符串中获取元素,如果是操作数,则直接进操作数栈,但如果获取的是操作符,则要分情况讨论,如下:(这里讨论优先级时暂不包括“(”和“)”的优先级)1.如果获取的操作符a的优先级高于操作符栈栈顶元素b的优先级,则a直接入操作符栈;2.如果获取的操作符a的优先级低于操作符栈栈顶元素b的优先级,则b出栈,a进栈,并且取出操作数栈的栈顶元素m,再取出操作数栈新的栈顶元素n,如果b为+,则用n+m,若为减号,则n-m,依此类推,并将所得结果入操作数栈;3.如果获取的是“(”,则直接进操作符栈;4.如果获取的是“)”,则操作符栈的栈顶元素出栈,做类似于情况2的计算,之后把计算结果入操作数栈,再取操作符栈顶元素,如果不是“(”,则出栈,重复操作,直到操作符栈顶元素为“(”,然后“(”出栈;5.当表达式中的所有元素都入栈后,看操作符栈中是否还有元素,如果有,则做类似于情况2 的计算,并将结果存入操作数栈,则操作数栈中最终的栈顶元素就是所要求的结果。
二.中缀转后缀及对后缀表达式计算的设计思想:中缀转后缀时主要用了一个操作符栈和一个用来存放后缀表达式的栈,从表达式中依次获取元素,如果获取的是操作数,则直接存入s3栈中,如果获取的是操作符也需分情况讨论,如下:(这里讨论优先级时暂不包括“(”和“)”的优先级)1. 如果获取的操作符a的优先级高于操作符栈栈顶元素b的优先级,则a直接入操作符栈;2. 如果获取的操作符a的优先级低于操作符栈栈顶元素b的优先级,则b出栈,a进栈,并且将b存入到操作符栈中;3.如果获取的是“(”,则直接进操作符栈;4.如果获取的是“)”,则操作符栈的栈顶元素出栈,并依次存入到操作符栈中,直到操作符栈栈顶元素为“(”,然后将“(”出栈;5.当表达式中的所有元素都入栈或存入到操作符栈之后,看操作符栈中是否还有元素,如果有,则依次出栈,并且依次存入到操作符栈中,最后打印操作符栈中的字符串,则此字符串即为要求的后缀表达式。
用两种方式实现表达式自动计算
数据结构(双语)——项目文档报告用两种方式实现表达式自动计算专业:网络工程班级:一班指导教师:吴亚峰姓名:陈金广学号:200801040102目录一、设计思想 (03)二、算法流程图 (03)三、源代码 (06)四、运行结果 (18)五、遇到的问题及解决 (19)六、心得体会 (20)一、设计思想程序代码是用两种算法实现中缀表达式转后缀表达式,并计算出表达式的值。
第一种算法是给出一个中缀表达式,编译运行后输出后缀表达式,并计算出后缀表达式的值。
首先,先创建两个数组,一个用于存储输入的中缀表达式,并以“#”结束,一个用于输出后缀表达式。
创建一个操作符栈,初始化并写好出栈入栈函数,用操作符栈存储操作符。
对中缀表达式进行遍历时,遇到数值就直接输入要输出后缀表达式的数组,遇到操作符时,首先对操作符的优先级进行设置,“*”,“/”,“%”的优先级设置为最高,“+”“-”的优先级低于前三个符号,“#”的优先级设置为最低。
对操作符栈进行操作时首先将“#”放入栈顶。
判断栈顶操作符与当前操作符优先级的大小,若当前操作符优先级大的话直接入栈,若当前操作符小于或者等于栈顶运算福的话栈顶操作符出栈,并输入后缀表达式所在的数组,当前操作符再入栈。
遇到“(”时,此时认为“(”的优先级为最高,直接入栈,但是当它入栈后优先级变为最小,当栈顶为“(”时操作符可以直接入栈,其他操作符直接入栈直至遇到“)”时,与“(”配对,括号之间的所有的操作符全部出栈并输入后缀表达式。
继续遍历中缀表达式。
当遍历到“#”时认为遍历中缀表达式结束。
此时操作符栈所有操作符出栈并输入后缀表达式,打印后缀表达式。
得到后缀表达式后,声明并初始化数值栈,写出入栈出栈函数,对后缀表达式进行遍历,遇到数值直接入栈,每遇到操作符,从数值栈栈顶取两个数进行运算,将运算结果入数值栈,继续遍历后缀表达式直至表达式结束,得到的结果就是后缀表达式的计算值。
第二种算法不将中缀表达式转换为后缀表达式,而是直接对中缀表达式进行操作,开始声明并初始化栈,一个操作符栈,一个数值栈。
(完整版)数学表达式计算(c语言实现)
一、设计思想计算算术表达式可以用两种方法实现:1.中缀转后缀算法此算法分两步实现:先将算术表达式转换为后缀表达式,然后对后缀表达式进行计算.具体实现方法如下:(1)中缀转后缀需要建一个操作符栈op和一个字符数组exp,op栈存放操作符,字符数组用来存放转换以后的后缀表达式。
首先,得到用户输入的中缀表达式,将其存入str数组中。
对str数组逐个扫描,如果是数字或小数点,则直接存入exp数组中,当扫描完数值后,在后面加一个#作为分隔符。
如果是操作符,并且栈为空直接入栈,如果栈不为空,与栈顶操作符比较优先等级,若比栈顶优先级高,入栈;如果比栈顶优先级低或相等,出栈将其操作符存到exp数组中,直到栈顶元素优先等级低于扫描的操作符,则此操作符入栈;如果是左括号,直接入栈,如果是右括号,出栈存入exp数组,直到遇到左括号,左括号丢掉。
然后继续扫描下一个字符,直到遇到str中的结束符号\0,扫描结束。
结束后看op栈是否为空,若不为空,继续出栈存入exp数组中,直到栈为空.到此在exp数组最后加结束字符\0。
我们就得到了后缀表达式。
(2)后缀表达式计算此时需要一个数值栈od来存放数值。
对exp数组进行逐个扫描,当遇到数字或小数点时,截取数值子串将其转换成double类型的小数,存入od栈中。
当遇到操作符,从栈中取出两个数,进行计算后再放入栈中。
继续扫描,知道扫描结束,此时值栈中的数值就是计算的结果,取出返回计算结果。
2。
两个栈实现算法此算法需要两个栈,一个值栈od,一个操作符栈op。
将用户输入的数学表达式存入str数组中,对其数组进行逐个扫描。
当遇到数字或小数点,截取数值子串,将其转换成double类型的数值存入od栈中;当遇到左括号,直接入op栈;遇到右括号,op栈出栈,再从值栈od中取出两个数值,计算将其结果存入值栈中,一直进行此操作,直到操作符栈栈顶为左括号,将左括号丢掉。
如果遇到操作符,若op栈为空,直接入栈;若栈不为空,与栈顶元素比较优先等级,若比栈顶操作符优先等级高,直接入op栈,如果低于或等于栈顶优先等级,op栈出栈,再从值栈中取出两个数值,计算将其结果存入值栈中,一直进行此操作,直到栈顶优先等级低于扫描的操作符等级,将此操作符入op 栈。
用两种方式实现表达式自动计算培训资料
用两种方式实现表达式自动计算数据结构(双语)——项目文档报告用两种方式实现表达式自动计算专业:计算机科学与技术应用班级:指导教师:吴亚峰姓名:学号:目录一、设计思想 (01)二、算法流程图 (01)三、源代码 (03)四、运行结果 (15)五、遇到的问题及解决 (16)六、心得体会 (17)一、设计思想A: 中缀表达式转后缀表达式的设计思想:我们借助计算机计算一个算数表达式的值,而在计算机中,算术表达式是由常量,变量,运算符和括号组成。
由于运算符的优先级不同又要考虑括号。
所以表达式不可能严格的从左到右进行,因此我们借助栈和数组来实现表达式的求值。
栈分别用来存储操作数和运算符。
在计算表达式的值之前,首先要把有括号的表达式转换成与其等值的无括号的表达式,也就是通常说的中缀表达式转后缀表达式。
在这个过程中,要设计两个栈,一个浮点型的存储操作数,用以对无符号的表达式进行求值。
另一个字符型的用来存储运算符,用以将算术表达式变成无括号的表达式;我们要假设运算符的优先级:( ) , * /, + - 。
首先将一标识号‘#’入栈,作为栈底元素;接着从左到右对算术表达式进行扫描。
每次读一个字符,若遇到左括号‘(’,则进栈;若遇到的是操作数,则立即输出;若又遇到运算符,如果它的优先级比栈顶元素的优先级数高的话,则直接进栈,否则输出栈顶元素,直到新的栈顶元素的优先级数比它低的,然后将它压栈;若遇到是右括号‘)’,则将栈顶的运算符输出,直到栈顶的元素为‘(’,然后,左右括号互相底消;如果我们设计扫描到‘#’的时候表示表达式已经扫描完毕,表达式已经全部输入,将栈中的运算符全部输出,删除栈底的标识号。
以上完成了中缀表达式转后缀表达式,输出无括号的表达式,若遇数值,操作数进栈;若遇运算符,让操作数栈的栈顶和次栈顶依次出栈并与此运算符进行运算,运算结果入操作数栈;重复以上的步骤,直到遇到‘#’,则此时栈中的结果便是所求的后缀表达式的值,接着输出结果。
数据结构课程设计---用两种方式实现表达式自动计算
一、设计思想(一)中缀转后缀的设计思想设计一个能实现表达式自动求值计算,算术表达式由操作数、算符和括号组成。
由于运算符的优先级不同还要考虑括号。
所以表达式不可能一直的从左到右进行,所以就借助栈来实现这个表达式的求值。
首先要把算术表达式变换成与之等值的无括号表达式,也就是中缀转后缀,它也是这个算法的关键。
设计两个栈,一个为字符型的,存放运算符,用以将算术表达式变成无括号的表达式;另一个浮点型的,存放操作数,用以对无符号的表达式进行求值。
我们要假设运算符的优先级:( ) , * /, + - 。
首先将一左括号‘(’入栈,作为栈底元素;接着从左到右对算术表达式进行扫描。
每次读一位,若遇到左括号‘(’,则进栈;若遇到的是操作数,则立即输出;若又遇到运算符,如果它的优先级比栈顶元素的优先级数高的话,则直接进栈,否则输出栈顶元素,直到新的栈顶元素的优先级数比它低的,然后将它压栈;若遇到是右括号‘)’,则将栈顶的运算符输出,直到栈顶的元素为‘(’,然后,左右括号互相底消;到设计的结束标志的时候表示表达式已经扫描完毕,表达式已经全部输入,将栈中的运算符全部输出,删除栈底的左括号。
以上完成了中缀表达式转后缀表达式,输出无括号的后缀表达式。
读后缀表达式,若遇数值,操作数进栈;若遇运算符,让操作数栈的栈顶和次栈顶依次出栈并与此运算符进行运算,运算结果入操作数栈;重复这个步骤,直到遇到结束标志,则此时栈中的结果便是所求的后缀表达式的值,接着输出结果。
以上就是设计这个算法的主要的思想。
(二) 直接计算的设计思想直接计算其实跟上一个相似,它是在上面扫两遍的思想进行修改的得来。
首先,要建立两个栈,一个为字符型的,存放运算符,另一个浮点型的,存放操作数,我们开始对表达式进行扫描。
首先要确定运算符的优先级:(、)、*、/、+、-。
如果扫描到的是数字符号,把它们转换成浮点型数据或其他可运算的数据类型,存入操作数栈中。
如果扫描到的是运算符号,第一个运算符进栈,遇到‘(’存入运算符栈中,我们按照第一种算法的方法将表达式依次扫描。
c两种方法实现表达式的计算
数据结构(双语)——项目文档报告用两种方式实现表达式自动计算专业:网络工程班级:网络1班指导教师:吴亚峰姓名:王嘉宇学号:201214620111目录一、设计思想 (01)二、算法流程图 (01)三、源代码 (04)四、运行结果 (12)五、遇到的问题及解决 (13)六、心得体会 (14)一、设计思想(1)先将中缀表达式转化为后缀表达式,再通过计算后缀表达式求表达式的值。
第一遍扫描中缀表达式,需要一个运算符栈和一个数组。
运算符栈用来存放运算符,数组用来存放转换成的后缀表达式。
首先将中缀表达式挨个扫描。
如果是数字,则直接放在后缀表达式数组中,依次存放。
如果扫描到的是运算符,则按照以下规则存放:栈空时,任何运算符可直接入栈。
栈不空是,如果栈中运算符的优先级高于或等于将要放入栈中的运算符的优先级,则将栈中运算符出栈,放入后缀表达式数组中,直到栈中运算符优先级低于将要放入栈中的运算符的优先级,此时将此运算符放入运算符栈中。
如果遇到左括号,则直接将左括号入栈,左括号入栈后优先级最低,其他运算符可直接放入。
如果遇到右括号,则将运算符栈中的运算符依次取出放到后缀表达式数组中,直到遇到左括号为止,此时将左括号从栈顶删除。
按此方法,直到后缀表达式转换成功。
第二遍扫描后缀表达式,此时需要一个数栈。
扫描时如果遇到数字,则直接放到数栈中。
如果遇到运算符,则将数栈中两个数取出,先取出的放在运算符后面,后取出的放在运算符前面,进行运算符运算。
将运算的结果放入栈中。
之后接着扫描后缀表达式。
另外因为运算数的位数不一定而且还有小数点,所以在扫到一个数时要判断这个数的位数,将这个完整的运算数字符串整个取出,这需要用到一个辅助索引。
当栈中只有一个数字时,这个数字就是我们要求的表达式的值。
(2)直接计算表达式的值。
这种方法需要两个栈,一个运算符栈,一个数栈。
只需扫描一遍中缀表达式,边运算边入栈。
当扫描到的为数字是,将其放入数栈中,然后扫描下一个字符。
计算式函数自动计算公式
如何使用计算式函数自动计算公式计算式函数是一种在电子表格软件中非常常用的功能,它可以帮助用户自动计算各种公式。
以下是一些使用计算式函数自动计算公式的技巧和提示。
1. SUM函数:这是计算电子表格中一列或一行数值之和的最基本的计算式函数。
要使用SUM函数,只需选择需要计算的列或行并在其上输入“=SUM(选择该列或行)”即可。
2. AVERAGE函数:与SUM函数类似,AVERAGE函数也是用于计算一列或一行平均值的函数。
要使用AVERAGE函数,只需输入“=AVERAGE(选择该列或行)”即可。
3. MAX和MIN函数:MAX和MIN函数分别用于寻找一列或一行的最大和最小值。
要使用MAX函数,只需输入“=MAX(选择该列或行)”;要使用MIN函数,只需输入“=MIN(选择该列或行)”。
4. IF和IFERROR函数:IF函数可以根据特定条件选择计算式函数要执行的操作。
例如,如果一个单元格中的值大于10,则执行AVERAGE函数;否则执行SUM函数。
“=IF(A1>10,AVERAGE(A1:A5),SUM(A1:A5))”即可。
IFERROR函数用于处理错误,当计算式函数发生错误时,可以使用IFERROR函数将错误信息替换为特定的字符串。
例如,“=IFERROR(SUM(A1:A5),“错误信息”)”。
5. VLOOKUP和HLOOKUP函数:这两个函数用于在表格中查找特定条件并返回相应的值。
VLOOKUP函数用于垂直方向,HLOOKUP函数用于水平方向。
例如,“=VLOOKUP(A1,A2:B5,2,FALSE)”表示在范围A2:B5中查找A1的值,并返回查找结果的第二列。
通过以上技巧和提示,相信您可以更加高效地使用计算式函数自动计算公式。
俩种方法实现表达式求值
一、设计思想用中缀式实现表达式自动计算,可以先定义两个栈。
一个称为OPTR,用以寄存运算符;另一个称做OPND,用以寄存操作数或运算结果。
算法的基本思想是:(1)首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元素。
(2)依次读入表达式中每个字符,若是操作数则进OPND栈,若是运算符则和OPTR栈的栈顶运算符比较优先权后作相应操作,若栈顶元素优先权低于读入的运算符,则入栈;若栈顶元素优先权等于读入的运算符,则出栈(相当于是把括号去掉);若栈顶元素优先权高于读入的运算符,则从OPND取出两个操作数分别放到变量里,再从OPTR里取出运算符做运算,然后将运算结果再放入OPND栈里。
直至整个表达式求值完毕(即OPTR栈的栈顶元素和当前读入的字符均为“#”)。
(3)输出结果。
用后缀式实现表达式自动计算,算法的基本思想是:(1)在主函数定义两个数组,一个数组存放中缀表达式,一个存放后缀表达式,在主函数里定义一个函数,通过调用函数实现中缀式转为后缀式。
(2)首先把输入的表达式放入中缀表达式数组,通过调用实现中缀转后缀,具体过程是定义一个数组存放操作数,定义一个栈存放运算符,当有括号时取两个操作数作运算,再把结果放到后缀式数组。
(3)在通过调用函数对后缀表达式求值。
(4)最后把中缀式,后缀式与结果打印出来。
二、算法流程图图1中缀式算法流程图图2后缀式算法流程图三、源代码下面给出的是用中缀式算法实现的程序的源代码,#include <stdio.h>#include <math.h>#include <string.h>#include <stdlib.h>#define true 1#define false 0#define STACK_SIZE 50char opt[7]={'+','-','*','/','(',')','#'};intisp[7][7]={{3,3,1,1,1,3,3},{3,3,1,1,1,3,3},{3,3,3,3,1,3,3},{3,3,3,3,1,3,3},{1,1,1,1,1,2,0},{3,3,3,3,0,3,3},{1,1,1,1,1, 0,2}};typedef struct{char optr[STACK_SIZE];int top;}stack;typedef struct{char opnd[STACK_SIZE];int top;}dstack; /*定义栈*/void InitStack(stack *s){s->top=-1;}void InitStacks(dstack *s){s->top=-1; /*初始化栈*/}int isempty(stack *s){if(s->top==-1)return true;elsereturn false;}int isemptyd(dstack *s){if(s->top==-1)return true;elsereturn false; /*判断栈是否为空*/}int isfull(stack *s){if(s->top==(STACK_SIZE-1))return true;elsereturn false;}int isfulld(dstack *s){return(s->top==(STACK_SIZE-1)?true:false); /*判断栈是否满*/ }int push(stack *s,char c){if(isfull(s)){printf("stack is full!\n");return false;}else{s->top++;s->optr[s->top]=c;return true;}}int pushd(dstack *s,int n){if(isfulld(s)){printf("dstack is full!\n");return false;}else{s->top++;s->opnd[s->top]=n;return true;}} /*入栈*/ int pop(stack *s,char *c){if(isempty(s)){printf("stack is empty!\n");return false;}else{*c=s->optr[s->top];s->top--;return true;}}int popd(dstack *s,int *n){if(isemptyd(s)){printf("stack if empty!\n");return false;}else{*n=s->opnd[s->top];s->top--;return true;}} /*出栈*/char getoptr(stack *s){if(isempty(s)){printf("stack is empty!\n");return false;}elsereturn s->optr[s->top];}int getopnd(dstack *s){if(isemptyd(s)){printf("stack is empty!\n");return false;}elsereturn s->opnd[s->top];}int isoptr(char ch){int i;for(i=0;i<7;i++){if(opt[i]==ch)return true;}return false;}int compare(char ch1,char ch2){int i,j,k;for(i=0;i<7;i++){if(ch1==opt[i])j=i;if(ch2==opt[i])k=i;}return isp[j][k];}int compute(int a,char optr,int b){int result;switch(optr){case'+': result=a+b;break;case'-': result=a-b;break;case'*': result=a*b;break;case'/': result=a/b;break;}return result;}int execute(){int i=0,temp,j,k,m;char c,op;char *ch;stack optr;dstack opnd;InitStack(&optr);InitStacks(&opnd);push(&optr,'#');printf("请输入表达式以'#'结束\n");ch=(char *)malloc(50*sizeof(char));gets(ch);c=ch[i++];while(c!='#' || getoptr(&optr)!='#'){if(!isoptr(c)){temp=c-'0';c=ch[i++];while(!isoptr(c)){temp=temp*10+c-'0';c=ch[i++];}pushd(&opnd,temp);}else{switch(compare(getoptr(&optr),c)){case 1:push(&optr,c);c=ch[i];i++;break;case 2:pop(&optr,&op);c=ch[i++];break;case 3:pop(&optr,&op);popd(&opnd,&j);popd(&opnd,&k);m=compute(k,op,j);pushd(&opnd,m);break;case 0:printf("wrong input!\n");return false;}}}m=getopnd(&opnd);return m;}void main(){int result;result= execute();printf("结果是%d\n",result);}下面给出的是用后缀式算法实现的程序的源代码,#include <stdio.h>#include <malloc.h>#include<process.h>#define MaxSize 50void trans(char *exp,char *postexp)/*中缀式变后缀式函数*/{struct{char data[MaxSize];/*存放运算符*/int top;} op;int i=0;op.top=-1;while(*exp!='\0'){switch(*exp){case '(':op.top++;op.data[op.top]=*exp;exp++;break;case ')':while(op.data[op.top]!='('){postexp[i++]=op.data[op.top];op.top--;}op.top--;exp++;break; /*等于左括号时,要释放左括号,即op.top--*/case '+':case '-':while(op.top!=-1&&op.data[op.top]!='(')/*为加减乘除是都比新进的加减号优先级高,固要先出站再入*/{postexp[i++]=op.data[op.top];op.top--;}op.top++;op.data[op.top]=*exp;exp++;break;case '*':case '/':while(op.data[op.top]=='*'||op.data[op.top]=='/'){postexp[i++]=op.data[op.top];op.top--;}op.top++;op.data[op.top]=*exp;exp++;break;case ' ':break;default:while(*exp>='0'&&*exp<='9'){postexp[i++]=*exp;exp++;}postexp[i++]='#';/*用#标识一个数值串结束*/ }}while(op.top!=-1)/*栈中的剩余符号,按优先级依次入栈*/{postexp[i++]=op.data[op.top];op.top--;}postexp[i]='\0';}float compvalue(char *postexp)/*后缀式求值运算函数*/{struct{float data[MaxSize];int top;} st;float a,b,c,d;st.top=-1;while(*postexp!='\0'){switch(*postexp){case '+':a=st.data[st.top];/*退栈取数值a,b;符号前已有数值*/st.top--;b=st.data[st.top];st.top--;c=b+a;st.top++;st.data[st.top]=c;break;case '-':a=st.data[st.top];st.top--;b=st.data[st.top];st.top--;c=b-a;st.top++;st.data[st.top]=c;break;case '*':a=st.data[st.top];st.top--;b=st.data[st.top];st.top--;c=b*a;st.top++;st.data[st.top]=c;break;case '/':a=st.data[st.top];st.top--;b=st.data[st.top];st.top--;if(a!=0){c=b/a;st.top++;st.data[st.top]=c;}else{printf("\n\t除零错误!\n");exit(0);}break;default:d=0;while(*postexp>='0'&&*postexp<='9'){d=10*d+*postexp-'0'; /*将d赋值为10乘d与*postexp的ASCII值减数字0的ASCII值的和*/postexp++;}st.top++;st.data[st.top]=d;break;}postexp++;}return st.data[st.top];}int main(){char exp[MaxSize],postexp[MaxSize];while(scanf("%s",&exp)!=EOF){trans(exp,postexp);printf("中缀表达式: %s\n",exp);printf("后缀表达式: %s\n",postexp);printf("值: %g\n",compvalue(postexp));}return 0;}四、运行结果图3中缀式运行结果图图4后缀式运行结果图五、遇到的问题及解决这部分我主要遇到了如下两个问题,其内容与解决方法如下所列:●问题1描述:不知道如何定义栈。
WPS公式实现自动计算功能
WPS公式实现自动计算功能自动计算功能是WPS公式中的一项非常实用的功能,它可以帮助用户在输入数学公式时自动进行计算,省去了手动计算的繁琐过程。
本文将介绍如何在WPS公式中实现自动计算功能,以及使用该功能的一些技巧和注意事项。
一、实现自动计算功能的基本方法在WPS公式中实现自动计算功能有两种基本方法:使用自动求值功能和使用宏编程实现。
1. 使用自动求值功能WPS公式中自动求值功能可以通过设置公式的计算选项来实现。
首先,在WPS公式中输入需要进行计算的数学表达式或公式,然后选中该表达式或公式。
接下来,点击工具栏上的“计算选项”按钮,在弹出的对话框中选择所需的计算选项,如求和、求积、求平均等。
点击“确定”后,WPS公式将自动计算并显示结果。
2. 使用宏编程实现除了使用自动求值功能外,还可以使用宏编程来实现更复杂的自动计算功能。
首先,在WPS公式中打开宏编辑器,创建一个新的宏。
接下来,编写宏的代码,根据需要定义变量、函数和运算规则。
在代码编写完成后,保存并关闭宏编辑器。
然后,在输入需要计算的数学表达式或公式后,选择该表达式或公式,点击工具栏上的“运行宏”按钮,选择之前创建的宏,点击“确定”,WPS公式将自动执行宏的代码并显示计算结果。
二、使用自动计算功能的技巧和注意事项在使用WPS公式的自动计算功能时,以下是一些技巧和注意事项供您参考:1. 输入正确的数学表达式或公式:在输入数学表达式或公式时,要确保语法正确,避免出现错误。
可以使用括号来明确运算顺序,以确保计算结果的准确性。
2. 设置正确的计算选项:在使用自动求值功能时,要根据实际需要选择适当的计算选项。
不同的计算选项可以完成不同的数学运算,如求和、求积、求平均等。
3. 理解宏编程的基本语法:如果您选择使用宏编程来实现自动计算功能,需要对宏编程的基本语法有一定的了解。
可以参考WPS公式的宏编程帮助文档,学习如何定义变量、函数和运算规则。
4. 调试和测试宏的代码:在编写宏的代码时,可以使用调试和测试工具来检查代码的正确性。
提高工作效率的Excel技巧使用函数进行自动计算
提高工作效率的Excel技巧使用函数进行自动计算Excel是一款非常强大的电子表格软件,广泛应用于办公场所和个人生活中。
通过使用Excel的函数,我们可以实现自动计算,大大提高工作效率。
本文将介绍一些常用的Excel技巧,以帮助您更好地利用函数进行自动计算,提升工作效率。
一、常用的Excel函数1. SUM函数:用于计算一系列数字的总和。
例如,=SUM(A1:A5)可以计算A1到A5单元格的和。
2. AVERAGE函数:用于计算一系列数字的平均值。
例如,=AVERAGE(A1:A5)可以计算A1到A5单元格的平均值。
3. MAX函数和MIN函数:分别用于计算一系列数字中的最大值和最小值。
例如,=MAX(A1:A5)可以计算A1到A5单元格中的最大值。
4. COUNT函数:用于计算一系列单元格中包含数字的个数。
例如,=COUNT(A1:A5)可以计算A1到A5单元格中的数字个数。
二、自动计算技巧1. 自动填充:在Excel中,可以通过拖动填充柄来自动填充一列或一行的数据。
例如,我们可以在第一个单元格中输入1,然后将鼠标悬停在填充柄上方,当光标变为十字箭头时,按住鼠标左键拖动填充柄,即可自动填充一系列数字。
2. 快速求和:如果要计算一列数字的和,可以使用快捷键Alt+=来快速求和。
选中需要计算的单元格区域,然后按下Alt键和=键即可得到求和结果。
3. 条件求和:Excel提供了SUMIF函数和SUMIFS函数,可以根据指定的条件进行求和计算。
使用这两个函数可以更灵活地实现条件求和的功能。
4. 平均值快捷键:如果要计算一列数字的平均值,可以使用快捷键Ctrl+Shift+!来快速计算平均值。
选中需要计算的单元格区域,然后按下Ctrl、Shift和!键即可得到平均值。
三、提高工作效率的Excel技巧1. 设置自动计算:Excel默认情况下是开启自动计算的,即当我们修改了某个单元格的值时,相应的计算结果会自动更新。
C语言下表达式的自动计算(两种方式)(报告+源代码)
一、设计思想第一种算法:将中缀表达式转为后缀表达式,然后通过后缀表达式计算出算术表达式的结果。
核心思想:第一步:中缀变后缀。
首先,我们做出一个统一的Node结构体,结构体内部包含四个属性,分别是操作符的字符‘op’,char类型;操作符的优先级‘level’,int 类型;数字的浮点数数值‘od’,float类型;Node的标识符,int类型。
然后,定义一个Node结构体类型的数组*listNode,这里的*listNode用的是全局变量,为了方便在得到后缀表达式后,不需再传递给计算的方法。
定义一个存放操作符的栈,遍历用户输入的算术表达式(不考虑错误情况),在遍历的过程中如果遇到数字,直接将数字存放在*listNode里面;如果遇到了操作符,则判断操作符栈目前是不是为空,如果为空,直接将遇到的操作符放入操作符栈中,如果操作符栈不为空,那么观察操作符栈中栈顶的操作符,然后再次判断当前遇到的操作符的优先级是不是比栈顶的操作符的优先级高,如果是,那么将当前的操作符入操作符栈;如果不是,那么将操作符栈的栈顶操作符取出,追加到*listNode中,然后继续观察栈顶操作符,直到当前的操作符的优先级比栈顶操作符的优先级高或者操作符栈为空时,将当前操作符入操作符栈。
如果遇到了左括号,那么定义其优先级为最低,然后直接将左括号入操作符栈。
如果遇到了右括号,那么开始从操作符栈中取出操作符追加到*listNode中,直到遇到了与之对应的左括号,然后将左括号和右括号一起销毁。
当遍历完成了算术表达式之后,这时判断操作符栈是否为空,如果不为空,那么从操作符栈中依次取出栈顶操作符追加到*listNode中,直到操作符栈为空,那么就代表我们将中缀表达式转变成为了后缀表达式。
第二步:通过得到的后缀表达式,计算算术表达式。
首先,定义一个数字栈用来存放数值。
然后,遍历*listNode中的每一个Node,如果Node是一个数字,那么就将数字入数字栈,如果Node是一个操作符,那么就从数字栈中依次取出栈顶的两个数字,然后根据操作符计算这两个数字,将得到的结果再次入数字栈,直到遍历*listNode完成,最终数字栈中会只剩下一个Node,那就是我们计算出算术表达式的结果,将结果返回给main 函数用来输出。
用两种方式实现表达式自动计算
一、设计思想计算表达式有两种方法:第一种方法:直接计算表达式:具体实现思想如下:通过get()函数,输入所要计算的表达式。
调用calculate(char ch[])函数,然后先建立两个栈,一个数值栈,一个操作符栈,同时将两个栈初始化为空,利用while循环获取表达式字符,并对表达式字符进行判断,如果是空格则直接跳过,如果是0到9的数字或者小数点‘.’,则利用trans()函数把数字转化为浮点型的数,然后在将浮点型的数值压栈,如果是操作符,则先判断操作符栈是否为空,如果为空,则操作符直接入栈,如果不为空,则先判断是不是右括号,如果是,则将栈顶元素出栈,并将数值栈中的两个元素出栈,进行相应的运算,然后把结果入栈,直到遇到左括号为止,并且把左括号出栈,如果不为左括号,则比较所扫描元素与栈顶元素的优先级,如果所扫描元素的优先级高于栈顶元素的优先级,则把所扫描元素直接入栈,如果所扫描元素的优先级低于栈顶元素的优先级,则先判断栈顶是不是左括号,如果是左括号则直接入栈,如果不是左括号,则将栈顶元素出栈,并将数值栈中的两元素出栈,进行相应的运算,然后把结果放入数值栈中,知道所扫描元素的优先级高于栈顶元素的优先级为止,如果扫到了表达式的结尾,即扫到了‘\0’,则判断此时操作符栈是否为空,如果不为空,则把操作符栈中的操作符出栈,并将数值栈中的两个数值出栈进行相应的运算,然后压入数值栈,知道操作符栈为空为止。
最后将最后结果从数值栈中出栈,并返回此结果。
此时表达式就计算出了最后结果。
第二种方法:先把中缀表达式转化为后缀表达式,然后在对后缀表达式进行计算。
具体实现思想如下:1、中缀表达式转为后缀表达式:在主函数中通过gets()函数获得要进行计算的表达式,然后调用中缀转换函数transform(char exp[],char tem[]),然后先定义一个操作符栈,并初始化为空,利用while循环获得表达式字符,并进行判断,如果是空格则直接跳过,如果不是空格,则判断是不是0到9的数字或者小数点‘.’,如果是则把此数字字符赋给字符数组tem[],如果是操作符,则先判断操作符栈是不是为空,如果为空,则操作符直接压入栈中,如果不是为空,则判断是不是右括号,如果是右括号,则将栈顶元素出栈,赋给字符数组,tem[],知道遇到左括号为止,如果不是左括号,则比较所扫描元素与栈顶元素的优先级,如果所扫描元素的优先级高于栈顶元素的优先级,则直接入栈,如果所扫描元素的优先级小于栈顶元素的优先级,则判断栈顶元素是不是左括号,如果是左括号,则所扫描元素直接入栈,如果不是左括号则将栈顶元素出栈并赋给字符数组tem[],知道遇到所扫描元素的优先级高于栈顶元素的情况为止。
中缀表达式求值
一、设计思想用堆栈中缀法实现表达式自动计算的基本思路是:定义两个栈,一个为操作符栈,用来存放操作符的;另一个为操作数栈,用来存放操作数。
还有一个字符型数组,用来存放输入的表达式。
从数组中开始扫描第一个字符w,每扫描一个字符后,根据w的不同情况分别做以下处理:如果是操作符,那么判断w与操作符的栈顶的优先级。
如果大于,直接将w压入操作符栈。
如果小于,则将操作符的栈顶弹栈,再将操作数栈的栈顶和次栈顶弹栈,并和操作符的栈顶进行计算,结果直接进入操作数栈。
如果w不是操作符,判断它是整数还是小数,是一位的还是多位的。
如果操作符的栈顶元素是#,并且从表达式数组中扫描进来的也是#,运算结束,操作数的栈顶元素就是计算结果。
二、算法流程图中缀表达式求值算法流程图简单说明:将输入的字符表达式存到数组中,对数组中的元素进行遍历,当读入第一个字符时先判断它是不是操作数然后判断它是不是多位浮点型小数。
如果是操作符,就判断它的优先级和操作符栈栈顶的优先级,谁的优先级比较高,如果是栈顶的优先级大于输入的字符,那么将栈顶的元素a出栈,再从操作数栈弹出栈顶和次栈顶,并进行次栈顶和栈顶关于a的运算,结果送回到操作数栈,然后扫描下一个字符。
如果它是操作数,那么要判断它是一位数还是多位数,是小数还是整数,如果是小数或者是多位的,那么执行多位数处理程序。
三、源代码下面给出的是用中缀表达式求值算法实现的程序的源代码:#define N 50#include<ctype.h>#include<string.h>#include<stdio.h>#include<math.h>typedef struct{int top;double array[N];}NumStack;//操作数栈类型typedef struct{int top;char array[N];}OpStack;//操作符栈类型int Cint(char mychar){return (mychar-48);}//字符转换成数字void PushNum(NumStack *numstack,double num){numstack->top++;numstack->array[numstack->top-1]=num;}//操作数进栈void PopNum(NumStack *numstack,double*num){*num=numstack->array[numstack->top-1];numstack->top--;}//操作数出栈void PushOp(OpStack *opstack,char op){opstack->top++;opstack->array[opstack->top-1]=op;}//操作符进栈void PopOp(OpStack *opstack,char*op){*op=opstack->array[opstack->top-1];opstack->top--;}//操作符出栈double Calc(double a,double b,char c){double result;switch(c){case'+':result=a+b;break;case'-':result=a-b;break;case'*':result=a*b;break;case'/':result=a/b;break;}return result;}//计算两个操作数按c进行运算char Priority(char y,char x){char priority='<';switch(x){case'+':case'-':if(y=='('|| y=='#')priority='>';break;case'*':case'/':if(y=='('|| y=='#'|| y=='+'|| y=='-')priority='>';break;case'(':priority='>';break;case')':if(y=='(')priority='=';break;case'#':if(y=='#')priority='=';break;default:priority='E';}return priority;}//比较两个操作符的优先级void Process(NumStack *numstack,OpStack *opstack,char x){double a,b;char c;static double tempnum=0.00000000;static int len=10;static intdot=0,flags=0;if(isdigit(x) || x=='.'){if(x=='.')dot=1;else{if(dot==0)tempnum=tempnum*10+Cint(x);//整数部分两位以上的数else{tempnum=tempnum+(double)Cint(x)/len;//小数部分两位以上的数len*=10;}}}else{if(flags==0 &&x!='('){PushNum(numstack,tempnum);tempnum=0.00000000;len=10;dot=0;} switch(Priority(opstack->array[opstack->top-1],x)){case'>':PushOp(opstack,x);flags=0;break;case'<':PopOp(opstack,&c);PopNum(numstack,&b);PopNum(numstack,&a);PushNum(numstack,Calc(a,b,c));flags=1;Process(numstack,opstack,x);break;case'=':PopOp(opstack,&c);flags=1;break;default:printf("Wrong Express!");exit(0);}}}main(){NumStack numstack;OpStack opstack;//定义栈char s[N];int i=0;numstack.top=0;opstack.top=0;//初始化栈PushOp(&opstack,'#');//操作符栈底为#printf("\nEnter your expression and end it with #:");scanf("%s",s); for(i=0;i<strlen(s);i++)Process(&numstack,&opstack,s[i]);printf("The result is %f",numstack.array[numstack.top-1]);}。
用两种方式实现表达式自动计算
if(S1.top()=='(')
{
S1.pop(); //蹦出去‘(’
break;
}
}
}
else if(exp[i] == '+' || exp[i] == '-') //如果遇到了加后者减号
{
while(S1.empty() == false)
{
ch=S1.top();
⑶如果获取的是“(”,则直接进操作符栈;
⑸如果获取的是“)”,则操作符栈的栈顶元素出栈,做类似于情况2的计算,之后把计算结果入操作数栈,再取操作符栈顶元素,如果不是“(”,则出栈,重复操作,直到操作符栈顶元素为“(”,然后“(”出栈;
⑹当表达式中的所有元素都入栈后,看操作符栈中是否还有元素,如果有,则做类似于情况2的计算,并将结果存入操作数栈,则操作数栈中最终的栈顶元素就是所要求的结果。
{
S1.push(exp[i]);
}
else
{
printf("你输入的不对!!!");
a=1;
break; //异常处理
}
i++;
}
while(S1.empty() == false) //最后把S1中的所有运算符弹出栈
{ if(a==1)
{break;}
else
{tempStr[j++] = S1.top(); //进一个,蹦一个
⑷开始处理运算符。
⑸如果栈定的运算符的优先级低于读到的那个,那么就直接进栈,否则把栈里的都进数组里。
⑹运算完,直到读完为止。返回字符数组,后缀表达式就出来了。
excel 计算单元格里面的数学表达式
Excel是一款功能强大的电子表格软件,它不仅可以帮助用户进行数据处理和分析,还可以进行数学运算。
用户可以在Excel中利用计算单元格里面的数学表达式来实现自动计算,提高工作效率。
接下来,我们将详细介绍如何在Excel中计算单元格里面的数学表达式。
一、基本数学运算在Excel中,用户可以利用基本的数学运算符号来进行加减乘除等运算。
用户可以在单元格中输入“=A1+B1”来实现A1单元格和B1单元格的相加计算。
用户还可以使用“-”、“*”、“/”等运算符号来进行减法、乘法和除法运算。
通过这种方式,用户可以快速进行简单的数学运算,提高工作效率。
二、函数运算除了基本的数学运算符号,Excel还提供了丰富的数学函数来帮助用户进行复杂的数学计算。
用户可以利用SUM函数来实现多个单元格的求和运算,利用AVERAGE函数来实现多个单元格的平均值计算,利用MAX和MIN函数来实现多个单元格的最大值和最小值计算等。
这些函数可以帮助用户快速实现复杂的数学计算,提高数据分析的效率。
三、公式嵌套在实际的数学计算中,有时候需要进行多步的计算,这时可以利用公式嵌套来实现。
用户可以在一个公式中嵌套多个函数或运算符号来实现复杂的数学计算。
“=SUM(A1:A5)*B1”表示先对A1到A5单元格进行求和,然后再和B1单元格进行乘法运算。
通过公式嵌套,用户可以实现更灵活、更复杂的数学计算。
四、条件计算在实际的数据分析中,有时需要根据特定条件进行数学计算,这时可以利用条件计算来实现。
Excel提供了IF函数来帮助用户进行条件判断和计算。
用户可以利用IF函数来实现根据特定条件进行不同数学计算的功能。
“=IF(A1>0,B1*2,B1*3)”表示当A1大于0时,对B1进行乘2运算;否则对B1进行乘3运算。
通过条件计算,用户可以根据具体需求来进行灵活的数学计算。
五、图表分析除了数学计算,Excel还提供了丰富的图表分析功能来帮助用户进行数据可视化分析。
数学公式自动计算
数学公式自动计算数学公式是数学中的重要工具,用于描述和推导数学问题。
计算数学公式可以帮助我们解决各种数学问题,提高计算效率和准确性。
如今,随着计算机技术的发展,我们可以利用计算机编程实现数学公式的自动计算。
在数学中,有很多重要的公式可以被自动计算。
下面将介绍一些常见的数学公式及其自动计算方法。
一、代数和方程式的自动计算代数是数学中的一个重要分支,代数公式的计算是数学中最基本的操作之一、代数公式可以通过使用变量和运算符来表示数学问题。
1.一次方程的自动计算一次方程是数学中最简单的方程之一,可以表示为ax + b = 0的形式。
其中,a和b是已知常数,x是未知数。
通过编写程序,我们可以输入方程的系数a和b,然后计算出未知数x的值。
代码示例:```pythona = float(input("请输入方程的系数a:"))b = float(input("请输入方程的系数b:"))x=-b/aprint("方程的解为x =", x)```2.二次方程的自动计算二次方程是数学中常见的方程形式,可表示为ax² + bx + c = 0。
其中,a、b和c是已知常数,x是未知数。
通过编写程序,并使用求根公式,可以计算出二次方程的根。
代码示例:```pythonimport matha = float(input("请输入方程的系数a:"))b = float(input("请输入方程的系数b:"))c = float(input("请输入方程的系数c:"))delta = b**2 - 4*a*cx1 = (-b + math.sqrt(delta)) / (2*a)x2 = (-b - math.sqrt(delta)) / (2*a)print("一元二次方程的根为x1 =", x1)print("一元二次方程的根为x2 =", x2)```二、几何问题的自动计算几何是数学中的一个重要分支,用于研究空间和形状。
用两种方式实现表达式自动计算
一、设计思想本项目用两种方式实现表达式自动计算:一是,用扫两遍表达式的方法;二是,用扫一遍表达式的方法。
其算法如下:◆算法一:扫两遍表达式求值的基本思路是:先将中缀表达式转化为后缀表达式,再通过计算后缀表达式求表达式的值。
第一遍扫描中缀表达式,将其转换为后缀表达式,在这步中用到一个运算符栈和一个列表(用数组实现)。
当扫到一个数时,因为运算数的位数不一定而且还有小数点,所以需要判断运算数的位数,将这个运算数按原来的顺序挂到列表中;当扫到一个运算符时,如果栈空:运算符直接入栈。
栈不空时:遇到左括号,直接入栈;遇到右括号,则开始出栈挂到列表后,直到栈顶为左括号,左括号出栈;遇到加、减、乘、除、求余运算符号时,当栈顶的运算符优先级低于扫到的运算符,运算符入栈,否则运算符出栈挂到列表后,直到满足入栈条件;当扫描完整个中缀表达式,将栈里面的运算符全都出栈挂列表后。
另外,因为后缀表达式中两个运算数会连在一起,所以为了区分两个运算数,每当扫描到加、减、乘、除、求余运算符号和栈中运算符出栈挂表后,在列表中添加一个空格作为分隔符。
这样列表中的表达式就是对应的后缀表达式。
第二遍扫描后缀表达式,并计算,这步中用到一个栈来放扫描到的数。
当扫到一个数时,因为运算数的位数不一定而且还有小数点,所以在扫到一个数时要判断这个数的位数,将这个完整的运算数字符串整个取出,把这个字符串转化为数值型(如;利用atof()函数将字符串转换为浮点型等),将其入栈;当扫到一个运算符时,则出栈两个数,先出栈的数作为第一个运算数后出栈的作为第二个运算数,按照所扫描到的运算符进行计算,并将计算结果放到栈中。
当扫描完整个后缀表达式后,在栈中只有一个数,这个数就是我们所要求值的表达式的结果。
◆算法二:扫一遍表达式求值的基本思路是:用两个栈(一个字符栈、一个数字栈)边扫描边计算,最后在数字栈中所得的数就是计算结果。
扫描要求值的表达式,当扫描到一个数时,因为运算数的位数不一定而且还有小数点,所以在扫到一个数时要判断这个数的位数,将这个完整的运算数字符串整个取出,把这个字符串转化为数值型(如;利用atof()函数将字符串转换为浮点型等),将其入数字栈。
用两种方法实现表达式自动计算
一、设计思想计算算数表达式并求值,可以采取两种算法:1.先将算术表达式转化为后缀表达式,然后对后缀表达式进行计算。
2.直接对算术表达式进行计算。
下面依次对两种方法进行分析:第一种算法有两步1.先将算数表达式转化为后缀表达式。
在计算过程中,第一,要先建立一个存放操作符的栈和一个存放数字的数组。
首先对用户输入的表达式进行扫面,如果是数字或者是小数点,直接存入数组。
如果是操作符,就判断是否为空或者是否为“(”或者是否它的优先级大于操作符栈顶的优先级,如果是,就入栈,索引后移;如果它的优先级不大于栈顶操作符,栈顶的操作符出栈,进入数组,如此循环,直到栈顶的优先级小于扫描到的操作符的优先级的时候,操作符入栈,索引后移。
当遇到标识符\0时,扫描结束。
数组中存放的就是后缀表达式。
2.利用后缀表达式进行计算。
得到后缀表达式后,要计算就需要用到数值栈。
首先对后缀表达式进行扫描,遇到数字字符,将数字字符转化为浮点类型,放入数值栈中,遇到操作符,就从数值栈中取出两个数,进行计算后将计算结果再放入数值栈中,扫描下一个,最后的计算结果就存到了数值栈中,直接取出数值栈栈顶元素,就是计算的最后结果。
第二种算法首先要建立两个栈,一个存放操作符的栈,一个是存放数值的栈。
然后开始对用户输入的表达式进行扫描,如果是数值或是小数点,就将其转化为浮点型数据,然后进入数值栈;如果是操作符,当前索引下的操作符的优先级如果不大于栈顶操作符的优先级,就将栈顶操作符取出来,从数值栈中取出两个数值,进行计算,结果存入数值栈。
如此循环,直到栈顶操作符的优先级小于当前索引的操作符的优先级是,操作符入栈,然后对下一个字进行扫描。
如果是左括号,则不进行优先级的比较,直接入栈。
如果是右括号,则从数值栈中取两个操作数,符号栈中取出一个符号,然后进行计算后得数放入数栈中,不断进行此类操作,直到从栈中取出的是左括号为止,左括号丢弃,扫描下一个。
扫描结束后,数值栈中存放的数值就是计算产生的结果,最后把数值从数值栈中取出,就是所得的计算结果。
用两种方式实现表达式自动计算
数据结构(双语)——项目文档报告用两种方式实现表达式自动计算专业:计算机科学与技术班级:14接计指导教师:姓名:学号:目录一、设计思想 (03)二、算法流程图 (04)三、源代码 (06)四、运行结果 (13)五、遇到的问题及解决 (14)六、心得体会 (15)一、设计思想1.中缀转换后缀:⑴定义两个栈S1,与S2。
S1主要管转换专用,S2主要管计算专用。
⑵扫描字符串,如果是字符或者小数的,直接进栈。
⑶如果是“(”,同直接进栈,直到遇到“)”,为止。
⑷开始处理运算符。
⑸如果栈定的运算符的优先级低于读到的那个,那么就直接进栈,否则把栈里的都进数组里。
⑹运算完,直到读完为止。
返回字符数组,后缀表达式就出来了。
⑺然后计算后缀表达。
⑻开始依次扫描数组,如果是数,就进栈,如果是运算符,那么就把栈的数弹出一个,赋值给一个变量,再弹一个赋值一个变量,再进行计算,完后再进栈。
⑼重复过程,直到度完。
栈顶元素就是最终结果。
⑽结束。
2.中缀直接计算:⑴如果获取的操作符a的优先级高于操作符栈栈顶元素b的优先级,则a直接入操作符栈;⑵如果获取的操作符a的优先级低于操作符栈栈顶元素b的优先级,则b出栈,a进栈,并且取出操作数栈的栈顶元素m,再取出操作数栈新的栈顶元素n,如果b为+,则用n+m,若为减号,则n-m,依此类推,并将所得结果入操作数栈;⑶如果获取的是“(”,则直接进操作符栈;⑸如果获取的是“)”,则操作符栈的栈顶元素出栈,做类似于情况2的计算,之后把计算结果入操作数栈,再取操作符栈顶元素,如果不是“(”,则出栈,重复操作,直到操作符栈顶元素为“(”,然后“(”出栈;⑹当表达式中的所有元素都入栈后,看操作符栈中是否还有元素,如果有,则做类似于情况2 的计算,并将结果存入操作数栈,则操作数栈中最终的栈顶元素就是所要求的结果。
二、算法流程图1.后缀2.中缀直接计算三、源代码1.后缀表达式#include<stdio.h>#include <string.h>#include<stdlib.h>#include <string>#include <stack>#include<algorithm>#include "fstream.h"#define MAXN 1000using namespace std;stack<char> S1; //定义栈S1 ,转换专用stack<double> S2; //定义栈S2,计算专用char *tranfExp(char* exp) //变换后缀{char tempStr[1000];//保存后缀表达式的字符串char ch;int i=0,j=0;int a=0; //标记表达式是否正确专用/// i nt b=0; //标记数字格式是否正确待用while(exp[i] !='\0'){if((exp[i]>='0' &&exp[i]<='9')||exp[i]=='.') //数字直接进字符串{tempStr[j++] = exp[i];// tempStr[j] = ' ';}else if(exp[i] == '(' ) //左括号蹦进栈S1{S1.push(exp[i]);}else if(exp[i] == ')' ) //如果是右括号,就把左括号后面的运算符都进字符串{while(S1.empty() == false){tempStr[j++]=S1.top(); //括号里进数组S1.pop(); //进一个,蹦一个if(S1.top()=='('){S1.pop(); //蹦出去‘(’break;}}}else if(exp[i] == '+' || exp[i] == '-') //如果遇到了加后者减号{while(S1.empty() == false){ch=S1.top();if(ch == '+' ||ch == '-' ||ch == '(') //与栈顶比较优先级,同级直接进栈{S1.push(exp[i]);break;}else //不同级,S1栈里的东西都进字符串里{while(S1.empty() == false){tempStr[j++] = S1.top(); //进一个,蹦一个S1.pop();if(S1.top()=='(') //如果有括号就把括号前面的进串,括号后的不进break;}}}if(S1.empty()==true) //如果S1里的东西都进字符串了,变成空了,就把扫描遇到的东西,蹦进S1{ S1.push(exp[i]);}}else if(exp[i] == '*' || exp[i] == '/'){S1.push(exp[i]);}else{printf("你输入的不对!!!");a=1;break; //异常处理}i++;}while(S1.empty() == false) //最后把S1中的所有运算符弹出栈{ if(a==1){break;}else{tempStr[j++] = S1.top(); //进一个,蹦一个S1.pop(); }}tempStr[j] = '\0'; //最后一个赋值为空字符串结束的标志if(a==1)return 0;elsereturn tempStr; //返回得到的后缀表达式}double calcExp(char* exp) //计算{int i=0;while(exp[i] != '\0'){if((exp[i] >= '0' && exp[i] <= '9')||exp[i]=='.') //把数进栈S2,遇到运算符,就弹2个数计算,结果再进S2{if(exp[i]=='.') //小数处理专用 {double x=0;double y=0;x=S2.top();printf("X的值%f\n",x);S2.pop();i++;y=exp[i]-'0';printf("y的值%f\n",y);x=x+y/10;printf("X的值%f\n",x);S2.push(x);}else{S2.push(exp[i]-'0'); }printf("进栈计算的数%f\n",S2.top());}else if(exp[i] == '-'){double m = S2.top();S2.pop();double n = S2.top();S2.pop();S2.push(n-m);}else if(exp[i] == '+' ){double m = S2.top();// printf("M的值%d\n",m);S2.pop();double n = S2.top();// printf("N的值%d\n",n);S2.pop();S2.push(n+m);}else if(exp[i] == '/'){double m = S2.top();S2.pop();double n = S2.top();S2.pop();S2.push(n/m);}else if(exp[i] == '*'){double m = S2.top();S2.pop();double n = S2.top();S2.pop();S2.push(n*m);}i++;}return S2.top();}main(){char str[1000];char str1[1000];char* tranStr;int len;double rel; //最后结果tranStr = (char *)malloc(100*sizeof(char));printf("输入字符\n");scanf("%s",str);printf("转换成后缀表达式\n");tranStr = tranfExp(str);len=strlen(tranStr);puts(tranStr);for(int i=0;i<=len;i++) //直接传tranStr会发生莫名其妙的错误,所以重新定义了个数组,把串全传送过去{str1[i]=tranStr[i];}rel=calcExp(str1);printf("结果为%f\n",rel);}2.中缀直接计算#include<iostream>#include<string>#include<stack>using namespace std;int transform(char s[],char stored[])//转化{const int a[8]={-1,-1,2,1,0,1,0,2};//保存优先级int i,j,temp;stack<char> sk;for(i=0,j=0,temp=0;s[i]!='\0';i++)//j保存数组stored的有效数字的长度{if(s[i]>='0'&&s[i]<='9')temp=temp*10+s[i]-'0';else{if(temp!=0){stored[j++]=temp+'0';temp=0;}if(!sk.empty()&&sk.top()==')')//弹出)sk.pop();if(sk.empty())//空就压入sk.push(s[i]);else{if(a[s[i]-'(']==a[sk.top()-'('])//这里看看ASCii表就明白了{stored[j++]=sk.top();sk.pop();sk.push(s[i]);}else{if((a[s[i]-'(']<a[sk.top()-'(']&&s[i]!='(')||s[i]==')') {while(!sk.empty()&&sk.top()!='(')//停止标志{stored[j++]=sk.top();sk.pop();}if(!sk.empty())sk.pop();sk.push(s[i]);}elsesk.push(s[i]);}}}}stored[j++]=temp+'0';//最后的数字也要拿while(!sk.empty())//残余运算符{stored[j++]=sk.top();sk.pop();}return j;}int calcular(char stored[],int n){stack<int> cal;int i,x,y,result=0;for(i=0;i<n;i++){if(stored[i]=='+'||stored[i]=='-'||stored[i]=='*'||stored[i]=='/')//遇到运算符{y=cal.top();cal.pop();x=cal.top();cal.pop();switch(stored[i])//各种运算{case '+':result=x+y;break;case '-':result=x-y;break;case '*':result=x*y;break;case '/':result=x/y;}cal.push(result);//保存当前结果}elsecal.push(stored[i]-'0');}return result;}int main(){char s[1000];char stored[1000];int n,result;while(cin>>s){n=transform(s,stored);result=calcular(stored,n);cout<<result<<endl;}return 0;}四、运行结果1.后缀输入结果2.中缀直接计算输入结果五、遇到的问题及解决经过一个星期的写代码,我遇到了很多问题,并一一解决了,比如一些莫名其名的错误,都是思路没问题,但是呢,都是逻辑错误。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构(双语)——项目文档报告用两种方式实现表达式自动计算专业:计算机科学与技术应用班级:指导教师:吴亚峰姓名:学号:目录一、设计思想 (01)二、算法流程图 (01)三、源代码 (03)四、运行结果 (15)五、遇到的问题及解决 (16)六、心得体会 (17)一、设计思想A: 中缀表达式转后缀表达式的设计思想:我们借助计算机计算一个算数表达式的值,而在计算机中,算术表达式是由常量,变量,运算符和括号组成。
由于运算符的优先级不同又要考虑括号。
所以表达式不可能严格的从左到右进行,因此我们借助栈和数组来实现表达式的求值。
栈分别用来存储操作数和运算符。
在计算表达式的值之前,首先要把有括号的表达式转换成与其等值的无括号的表达式,也就是通常说的中缀表达式转后缀表达式。
在这个过程中,要设计两个栈,一个浮点型的存储操作数,用以对无符号的表达式进行求值。
另一个字符型的用来存储运算符,用以将算术表达式变成无括号的表达式;我们要假设运算符的优先级:( ) , * /, + - 。
首先将一标识号‘#’入栈,作为栈底元素;接着从左到右对算术表达式进行扫描。
每次读一个字符,若遇到左括号‘(’,则进栈;若遇到的是操作数,则立即输出;若又遇到运算符,如果它的优先级比栈顶元素的优先级数高的话,则直接进栈,否则输出栈顶元素,直到新的栈顶元素的优先级数比它低的,然后将它压栈;若遇到是右括号‘)’,则将栈顶的运算符输出,直到栈顶的元素为‘(’,然后,左右括号互相底消;如果我们设计扫描到‘#’的时候表示表达式已经扫描完毕,表达式已经全部输入,将栈中的运算符全部输出,删除栈底的标识号。
以上完成了中缀表达式转后缀表达式,输出无括号的表达式,若遇数值,操作数进栈;若遇运算符,让操作数栈的栈顶和次栈顶依次出栈并与此运算符进行运算,运算结果入操作数栈;重复以上的步骤,直到遇到‘#’,则此时栈中的结果便是所求的后缀表达式的值,接着输出结果。
以上就是设计这个算法的主要的思想。
设计思想的流程图详见图A;B: 直接计算表达式的值。
所谓的扫一遍就是当扫完一个表达式结果也就计算出来了,是在上面扫两遍的思想进行修改的得来,首先,我们要建立两个栈,一个为字符型的用来存放运算符,另一个浮点型的用来存放操作数。
我们开始对表达式进行扫描,首先我们要假设运算符的优先级:( ) , * /, + - 。
如果扫描到的是数字符号,把它们转换成浮点型数据,存入操作数栈中。
如果扫描到的是运算符号,第一个运算符进栈,遇到‘(’存入运算符栈中,我们按照第一种算法的方法将表达式依次扫描。
只不过不同的是,当每取得的一个运算符的时候,都要与栈顶的运算符进行比较,如果它的优先级小于栈顶运算符优先级时,取出栈顶运算符并从操作数栈中取栈顶两个数进行运算,得到的结果则要存回操作数栈,就这样边扫描边比较,再进行计算。
遇到“)”对运算符的处理相同。
扫描结束后,把运算符栈的元素和操作数栈里的数进行运算。
每次的运算结果再放入操作数栈,一直到计算到运算符栈空。
最后操作数栈的栈顶留下的操作数即表达式的计算结果。
以上就是设计这个扫一遍算法的主要的思想。
设计思想的流程图详见图B;二、算法流程图A:以下是中缀转后缀算法的流程图图2是中缀转后缀算法的流程图B:以下是扫一遍代码运算的流程图:图B是直接计算的流程图三、源代码A:下面给出的是用中缀表达式转后缀表达式算法实现的程序的源代码:#include <stdio.h> /*I/O函数*/#include <malloc.h>#include <stdlib.h>#define MAXLEN 100 /*对栈的最大存贮值进行定义*//*自定义两个栈*/typedef struct stackData{float data[MAXLEN];int top; /*指针*/}stackData; /*定义存储操作数的栈*/typedef struct stackChar{char data[MAXLEN];int top; /*指针*/}stackChar; /*用于定义存储操作符号的栈*//*对相应的函数和常量变量,指针进行声明*/int judgeFirst(char c); /*声明判定操作符优先级的函数*/int PushNum(stackData *p,float value); /* 入栈*/int PushChar(stackChar *p,char value);int PopNum(stackData *p,float *value); /* 出栈*/int PopChar(stackChar *p,char *value);float VisitNum(stackData * p);char visitChar(stackChar * p);float Compute(float a,char ch,float b); /* 操作函数,执行具体运算*/int Check(char *);stackData *Data; /*定义操作数栈,由指针data指出*/stackChar *Operation;stackData * InitNum();stackChar * InitChar();int i,j=0;float bl,blo; /*对变量进行声明*/float resoult,opA,opB;char operand[2],opChar; /*定义字符型数组和字符变量*/char recv[MAXLEN];float suffix[MAXLEN];char *ptRecv=NULL; /*定义字符型指针*/int main() /*主函数*/{printf("please enter tne formula:");while((scanf("%s",recv))!=EOF) /*判断循环的条件当输入EOF的时候停止*/ {Operation = InitChar();Data = InitNum();PushChar(Operation,'#');recv[strLen(recv)]='#'; /*将字符#赋予数组最后*/ptRecv = recv;for(i=0;i<strLen(ptRecv);i++) /*扫描表达式,判断循环的条件*/{if(recv[i]>='0' && recv[i]<='9' || recv[i]=='.') /*判断数值*/{double weight=0.1;int flag=0; /*定义变量flag,用来标志小数点*/float blo=0; /*定义浮点型变量*/blo=recv[i]-'0';while(recv[i+1]>='0' && recv[i+1]<='9' || recv[i+1]=='.') /*判定数值*/{if(recv[i+1]=='.') /*读到小数点*/flag=1;else{if(flag==0) blo=blo*10+recv[i+1]-'0'; /*将整数部分字符串转化为实数*/else{blo=blo+( recv[i+1]-'0' )*weight; /*将表示小数部分的字符也转化过来*/weight*=0.1; /*weight为小数位权*/}}i++;}suffix[j]=blo;j++; /*数值进入数组*/}else{if(recv[i]=='#') /*遇见字符#*/{while(visitChar(Operation)!='#') /*对操作符栈进行遍历*/{PopChar(Operation,&opChar);suffix[j]=opChar;j++; /*字符出栈进入数组*/}}else{if(judgeFirst(recv[i])>judgeFirst(visitChar(Operation))||visitChar(Operation)=='(') /*判断操作符的优先级高低*/ {PushChar(Operation,recv[i]); /*字符入栈*/}else{if(recv[i]==')') /*遇见字符)*/{while(visitChar(Operation)!='(') /*输出(之前的所有操作符*/{PopChar(Operation,&opChar);suffix[j]=opChar;j++; /*操作符进入数组*/}PopChar(Operation,&opChar);}else{while(judgeFirst(recv[i])<=judgeFirst(visitChar(Operation))) /*进栈的运算符优先级低时,先出栈后进栈*/{PopChar(Operation,&opChar);suffix[j]=opChar; /*出栈的进入数组*/j++;}PushChar(Operation,recv[i]); /*运算符进栈*/}}}}}printf("the suffix is:"); /*输出后缀表达式*/for(j=0;suffix[j]!='\0';j++){if((char)suffix[j]=='+'||(char)suffix[j]=='-'||(char)suffix[j]=='*'||(char)suffix[j]=='/') /*强制类型转换*/{printf("%6c",(char)suffix[j]); /*输出一个运算符*/PopNum(Data,&opA);PopNum(Data,&opB);resoult = Compute(opB,(char)suffix[j],opA); /*调用函数进行运算*/PushNum(Data,resoult); /*运算结果入栈*/}else{PushNum(Data,suffix[j]);printf("%10f",suffix[j]) /*输出后缀表达式*/;}}printf("\nthe Result is:%.2f\n\n",resoult); /*输出运算结果*/}return 0;}stackData * InitNum() /*初始化数值栈*/{stackData *p = (stackData *)malloc(sizeof(stackData)); /*取一段内存赋予数值栈*/ p->top = -1; /*定义栈底*/return p; /*返回数值栈*/}stackChar * InitChar() /*初始化操作符栈*/{stackChar *p = (stackChar *)malloc(sizeof(stackChar)); /*取一段内存赋予操作符栈*/ p->top = -1;return p;}int PushNum(stackData *p,float value) /*定义入栈函数*/{if(p->top < MAXLEN-1){p->top +=1; /*指针*/p->data[p->top] = value; /*入栈的数值为栈顶元素*/return 1;}else{return 0;}}int PushChar(stackChar *p,char value) /* 定义操作符入栈函数*/{if(p->top < MAXLEN-1) /*栈不能满*/{p->top +=1; /*指针*/p->data[p->top] = value; /*入栈字符为栈顶元素*/return 1;}else{return 0; /*栈溢出返回0*/}}int PopNum(stackData *p,float *value) /*定义数值出栈函数*/{if(p->top >= 0) /*判定栈不为空*/{*value = p->data[p->top];p->top -= 1; /*指针*/}return 1;}int PopChar(stackChar *p,char *value) /*定义操作符出栈函数*/ {if(p->top >= 0) /*判定栈不为空*/{*value = p->data[p->top];p->top -= 1; /*指针*/}return 1;}float VisitNum(stackData * p) /*定义数值栈遍历函数*/{if(p->top!=-1) /*判定栈是否为空*/return p->data[p->top];else return 0;}char visitChar(stackChar * p) /*定义操作符栈遍历函数*/{if(p->top!=-1) /*判定栈是否为空*/return p->data[p->top];else return 0;}int judgeFirst(char c) /*符号的优先级*/{switch(c){case '#': return 0; /*#的优先级*/case '+':return 1;case '-':return 1; /*减号的优先级*/case '*':return 2;case '/':return 2;case '(':return 3; /*左括号的优先级*/default : return -1;}}int strLen(char *L) /*计算字符串长度*/{int i = 0;for(;L[i]!='\0';i++); /*循环条件的判定*/if(L[0]=='-'||L[0]=='+'){i=i-1;}return i;}float Compute(float a,char ch,float b) /*数据运算*/{switch(ch){case '+':return a+b; /*返回加号数值运算结果*/case '-':return a-b;case '*':return a*b; /*返回乘号数值运算结果*/case '/':return a/b; /*返回除号数值运算*/default : return -1; }}B:下面给出的是直接计算的思想的代码实现:#include <stdio.h> /*I/O函数*/#include <malloc.h>#include <stdlib.h>#define MAXLEN 100 /*对栈的最大存储值进行声明*//*声明用来存储操作数和运算符的栈*/typedef struct stackData{float data[MAXLEN];int top;}stackData; /*定义操作数的栈*/typedef struct stackChar{char data[MAXLEN];int top;}stackChar; /* 用于定义运算符的栈*//*对函数进行声明*/int judgeFirst(char c); /*声明判定操作符优先级的函数*/ char visitChar(stackChar * p);int pushNum(stackData *p,float value); /* 操作数入栈*/int PushChar(stackChar *p,char value); /* 运算符入栈*/int PopNum(stackData *p,float *value); /* 操作数出栈*/int PopChar(stackChar *p,char *value); /* 运算符出栈*/float VisitNum(stackData * p);float Compute(float a,char ch,float b); /* 操作函数,执行具体运算*/int main() /*主函数*/{stackData * InitNum();stackChar * InitChar();int Check(char *);stackData *Data; /*定义操作数栈,由指针data指出*/stackChar *Operation; /*定义运算符栈,由指针Operation指出*/int i; /*对变量进行声明*/float dit,digit;float resoult,opA,opB;char operand[2],opChar; /*定义字符型数组和字符变量*/char recv[MAXLEN];char *ptRecv=NULL; /*定义字符型指针*/printf ("please enter the formula:");while((scanf("%s",recv))!=EOF) /*判断循环的条件当输入EOF的时候停止*/{Data = InitNum();Operation = InitChar();PushChar(Operation,'#');recv[strLen(recv)]='#'; /*将字符#赋予数组最后*/ptRecv = recv;for(i=0;i<strLen(ptRecv);i++) /*判定循环的条件*/{if(recv[i]>='0' && recv[i]<='9' || recv[i]=='.') /*判断值*/{double weight=0.1;int flag=0; /*定义整形变量flag,记录是否有小数点*/float digit=0; /*定义浮点型变量*/digit=recv[i]-'0';while(recv[i+1]>='0' && recv[i+1]<='9' || recv[i+1]=='.') /*判定数值*/{if(recv[i+1]=='.') /*读到小数点*/flag=1;else{if(flag==0) digit=digit*10+recv[i+1]-'0'; /*将整数部分字符串转化为实数*/else{digit=digit+( recv[i+1]-'0')*weight; /*将表示小数部分的字符也转化过来*/weight*=0.1; /*weight为小数位权*/}}i++;}pushNum(Data,digit); /*将数值进栈*/}else{if(recv[i]=='#') /*遇见字符#*/{while(visitChar(Operation)!='#') /*对操作符栈进行遍历*/{PopChar(Operation,&opChar); /*字符出栈*/PopNum(Data,&opA);PopNum(Data,&opB); /*数出栈*/resoult = Compute(opB,opChar,opA); /*调用运算函数*/pushNum(Data,resoult);}}else{if(judgeFirst(recv[i])>judgeFirst(visitChar(Operation))||visitChar(Operation)=='(')/*判断操作符的优先级高低*/ {PushChar(Operation,recv[i]); /*操作符进栈*/}else{if(recv[i]==')') /*当操作符为)时*/{while(visitChar(Operation)!='(') /*遍历操作符栈*/{PopChar(Operation,&opChar);PopNum(Data,&opA);PopNum(Data,&opB); /*从数值栈输出一个值*/resoult = Compute(opB,opChar,opA);pushNum(Data,resoult);/*结果放回栈里*/}PopChar(Operation,&opChar); /*输出操作符*/}else{while(judgeFirst(recv[i])<=judgeFirst(visitChar(Operation))) /*判断操作符的优先级高低*/{PopChar(Operation,&opChar);PopNum(Data,&opA); /*从数值栈输出数值*/PopNum(Data,&opB);resoult = Compute(opB,opChar,opA); /*调用运算函数*/pushNum(Data,resoult); /*将运算结果入栈*/}PushChar(Operation,recv[i]); /*将操作符入栈*/}}}}}printf("\nthe Result is:%.2f\n\n",resoult);/*输出扫描一遍的运算结果*/}return 0;}stackData * InitNum() /*初始化数值栈*/{stackData *p;p= (stackData *)malloc(sizeof(stackData)); /*取一段内存赋予数值栈*/p->top = -1; /*定义栈底*/return p; /*返回数值栈*/}stackChar * InitChar() /*初始化操作符栈*/{stackChar *p = (stackChar *)malloc(sizeof(stackChar)); /*取一段内存赋予操作符栈*/p->top = -1;return p;}int pushNum(stackData *p,float value) /*定义入栈函数*/{if(p->top < MAXLEN-1) {p->top +=1; /*指针*/p->data[p->top] = value; /*入栈的数值为栈顶元素*/return 1;}else{return 0;}}int PushChar(stackChar *p,char value) /* 定义操作符入栈函数*/ {if(p->top < MAXLEN-1){p->top +=1; /*指针*/p->data[p->top] = value; /*入栈字符为栈顶元素*/return 1;}else{return 0; /*栈溢出返回0*/}}int PopNum(stackData *p,float *value) /*定义数值出栈函数*/ {if(p->top >= 0) /*判定栈不为空*/{*value = p->data[p->top];p->top -= 1; /*指针*/}return 1;}int PopChar(stackChar *p,char *value) /*定义操作符出栈函数*/ {if(p->top >= 0) /*判定栈不为空*/{*value = p->data[p->top];p->top -= 1; /*指针*/}return 1;}float VisitNum(stackData * p) /*定义数值栈遍历函数*/ {if(p->top!=-1) /*判定栈是否为空*/return p->data[p->top];else return 0;}char visitChar(stackChar * p) /*定义操作符栈遍历函数*/ {if(p->top!=-1) /*判定栈是否为空*/return p->data[p->top]; /*返回栈顶的值*/ else return 0;}int judgeFirst(char c) /*符号的优先级*/{switch(c){case '#': return 0;case '+':return 1; /*加号的优先级*/case '-':return 1;case '*':return 2; /*乘号的优先级*/case '/':return 2; /*除号的优先级*/case '(':return 3;default : return -1;}}int strLen(char *L) /*计算字符串长度*/{int i = 0;for(;L[i]!='\0';i++); /*循环条件的判定*/if(L[0]=='-'||L[0]=='+'){i=i-1;}return i;}float Compute(float a,char ch,float b)/*数据运算*/{switch(ch){case '+':return a+b; /*返回加号数值运算*/case '-':return a-b; /*返回减号数值运算*/case '*':return a*b;case '/':return a/b; /*返回除号数值运算*/default : return -1;}}四、运行结果A:首先我们通过中缀表达式转换为后缀表达式来计算表达式图C:上图是利用中缀表达式转后缀表达式B:其次我们直接来计算表达式的值图D:这次是利用直接计算来实现的结果五、遇到的问题及解决这部分我主要遇到了如下几个个问题,其内容与解决方法如下所列:C语言中没有string类型,所以不能直接声明string类型的变量来存储输入的表达式,也不能直接声明一个字符串数组来存储截取的数字字符串。