实验报告 计算器程序

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验报告
学生姓名:学号:专业班级:网络工程
实验类型:□验证□综合■设计□创新实验日期:10.4.5 实验成绩:
实验2:栈和队列
一、实验目的
深入了解栈和队列的特性,学会在实际问题下灵活运用它们。

二、问题描述
表达式求值运算是实现程序设计语言的基本问题之一,也是栈应用的一个典型例子。

设计并演示用算符优先级对算术表达式的求解过程。

三、实验要求
1、算法优先级别如下:
'+', '-', '*', '/', '(', ')', '#'
'+' '>', '>', '<', '<', '<', '>', '>',
'-' '>', '>', '<', '<', '<', '>', '>',
'*' '>', '>', '>', '>', '<', '>', '>',
'/' '>', '>', '>', '>', '<', '>', '>',
'(' '<', '<', '<', '<', '<', '=', ' ',
')' '>', '>', '>', '>', ' ', '>', '>',
'#' '<', '<', '<', '<', '<', ' ', '='
2、以字符序列的形式从终端输入语法正确、不含变量的算术表达式,利用给出的算符优先级关系,实现对算术四则混合运算的求解过程。

?四、实验环境
PC微机
DOS操作系统或Windows 操作系统
Turbo C 程序集成环境或Visual C++ 程序集成环境
?五、实验步骤
根据给出的算符优先级,设置运算符栈和运算数栈;
在读入表达式的同时,完成运算符和运算数的识别处理,并将运算数的字符序列形式转换成整数形式,并进行相应的运算;
调试程序,检查输出结果;
实验小结。

?六、测试数据
输入数据:1+(20+4)/(4-1)
正确结果:9
输入数据:2*9-6-(20+4)/(4-1)
正确结果:4
七、实验报告要求
实验报告应包括以下几个部分:
1、问题描述;
2、算法的设计描述;
3、测试结果的分析与讨论。

4、设计与实现过程中的体会,进一步的改进设想。

实现算法的程序清单,应有足够的注释。

实验代码如下:
#include<iostream>
#include<cmath>
#include<cstdlib>
using namespace std;
#define MAX 1000
struct save1
{
float n[MAX];
int top;
}stack1;
struct save2
{
char n[MAX];
int top;
}stack2;
//stack1存储数字,stack2存储运算符号. bool stackempty(save1 s)//判断是否为空{
if (s.top== -1)
return 1;
else
return 0;
}
bool stackempty2(save2 s)//判断是否为空{
if (s.top== -1)
return 1;
else
return 0;
}
void push(save1 &s,float e)//将e入栈{
if(s.top==MAX-1)
{
cout<<"栈已满"<<endl;
return ;
}
s.top++;
s.n[s.top]=e;
}
void push2(save2 &s,char e)//将e入栈
if(s.top==MAX-1)
{
cout<<"栈已满"<<endl;
return ;
}
s.top++;
s.n[s.top]=e;
}
void pop(save1 &s,float &e)//将栈顶元素出栈,存到e中{
if(s.top==-1)
{ cout<<"栈为空"<<endl; }
else
{e=s.n[s.top]; s.top--; }
}
void pop2(save2 &s,char &e)//将栈顶元素出栈,存到e中{
if(s.top==-1)
{ cout<<"栈为空"<<endl; }
else
{e=s.n[s.top]; s.top--; }
}
int in(char e)//e在栈内的优先级别
{
if(e=='-' || e=='+') return 2;
if(e=='*' || e=='/') return 4;
if(e=='^') return 5;
if(e=='(') return 0;
if(e==')') return 7;
return -1;
}
int out(char e)//e在栈外的优先级别
{
if(e=='-' || e=='+') return 1;
if(e=='*' || e=='/') return 3;
if(e=='^') return 6;
if(e=='(') return 7;
if(e==')') return 0;
return -1;
void count(float a,char ope,float b)//进行计算并将计算结果入栈
{
float sum;
if(ope=='+') sum=a+b;
if(ope=='-') sum=a-b;
if(ope=='*') sum=a*b;
if(ope=='/') sum=a/b;
if(ope=='^') sum=pow(a,b);
push(stack1,sum);
}
int main()
{
int i=0,len,j,nofpoint,g=0;//len表示输入式子的长度。

g表示读入的字符是否是字母变量、数字以及运算符。

float a,b;//a、b用来存储操作数栈中弹出的操作数,便于代入函数中进行计算。

char line[MAX],operate,temp[20];
cout<<"请输入表达式:"<<endl;
cin>>line;
len=strlen(line);
stack1.top=-1;//将栈置为空
stack2.top=-1;//将栈置为空
while(1)
{
g=0;
if(isdigit(line[i]))//若读入的字符为数字,则继续判断下一个字符,直到下一个字符不是数字或者不是小数点,即可保证该操作数是完整的小数,然后将该数入操作数栈。

{
j=0; g=1;
nofpoint=0;//记录所存的数中小数点的个数
while(isdigit(line[i]) || line[i]=='.')
{
if(line[i]=='.') nofpoint++;
temp[j++]=line[i];
i++;
if(i>=len) break;
}
if( nofpoint>1 || (i<len&&(line[i]!='-' && line[i]!='+' && line[i]!='*' && line[i]!='/' && line[i]!='^' && line[i]!=')')) )
{ cout<<"表达式有错"<<endl; return 0; }//所存数中含有不止一个小数点,或者数字后面跟的不是“+、-、*、/、^、)”,则为错误
temp[j]='\0';
b=atof(temp);
push(stack1,b);
if(i>=len) break;
}
else
{
if(line[i]=='-' || line[i]=='+' || line[i]=='*' || line[i]=='/' ||
line[i]=='^' || line[i]=='(' || line[i]==')' ) //若读入的字符为运算符的情况
{
g=1;
if(line[i]=='(' && i==len) { cout<<"表达式有错"<<endl; return 0; }// “(”放表达式最后面,错误if(line[i]=='-' || line[i]=='+' || line[i]=='*' || line[i]=='/' || line[i]=='^')
{
if(i==len) { cout<<"表达式有错"<<endl; return 0; }//“+、-、*、/、^”放在表达式最后面,错误
if( (!isdigit(line[i+1])) && (!isalpha(line[i+1])) && line[i+1]!='(')//“+、-、*、/、^”后面跟的不是数字或者变量,错误
{ cout<<"表达式有错"<<endl; return 0; }
}
if(line[i]=='-' && (i==0 || line[i-1]=='(' ))//运算符是负号
{
push(stack1,0);
push2(stack2,line[i]);
i++;
}
else
{ //读入的运算符与运算符栈的栈顶元素相比,并进行相应的操作
if(in(stack2.n[stack2.top])<out(line[i])||stackempty2(stack2)) { push2(stack2,line[i]);i++;}
else
if(in(stack2.n[stack2.top])==out(line[i])) {i++; stack2.top--;}
else
if(in(stack2.n[stack2.top])>out(line[i]))
{
pop(stack1,a);
pop(stack1,b);
pop2(stack2,operate);
count(b,operate,a);
}
if(i>=len) break;
}
}
else
{
if(isalpha(line[i]))//读入的字符是字母变量的情况
{
g=1;
cout<<"请输入变量";
while( isalpha(line[i])) { cout<<line[i]; i++; }
cout<<"的值"<<endl;
cin>>b;
push(stack1,b);
if(i>=len) break;
if(line[i]!='-' && line[i]!='+' && line[i]!='*' && line[i]!='/' && line[i]!='^' && line[i]!=')')//变量后面跟的不是“+、-、*、/、^、)”,则为错误
{ cout<<"表达式有错"<<endl; return 0; }
}
}
}
if(g==0) { cout<<"表达式有错"<<endl; return 0; }//g=0表示该字符是不符合要求的字符
}
while(stack2.top!=-1)//读入结束后,继续进行操作,直到运算符栈为空
{
pop(stack1,a);
pop(stack1,b);
pop2(stack2,operate);
if(operate=='(' || operate==')') //括号多余的情况
{ cout<<"表达式有错"<<endl; return 0; }
count(b,operate,a);
}
cout<<stack1.n[stack1.top]<<endl;
return 0;
}
整型数运行结果如下:
浮点数运行结果如下:
八、思考题
如何实现前缀算术表达式、后缀表达式的求解?
答:用栈来实现表达式的中缀表示法变后缀要用一个字符型数组OPTR作为栈,存放括号和运算符。

设字符“#”为表达式的终止符,方法如下:
先将一个左括号“(”压入栈OPTR,作为栈底元素,输入时以“#”作为输入的结束标志。

依次读入表达式中的字符,对于每一个字符有三种情况:
第一种情况是——数字;处理方式:将字符直接赋值到后缀表达式串中。

第二种情况是——非数字非运算符;处理方式:结束。

第三种情况是——运算符;处理情况按运算符与栈顶运算符的三种优先关系;
①大于栈顶优先级:将字符直接赋值到后缀表达式串中。

②等于栈顶优先级:将栈顶元素退栈,处理表达式中下一个字符。

③小于栈顶优先级:将栈顶元素退栈,并将推出栈的元素输出到后缀表示式串中int transExpression(char *str1,char *str2)
{ /*将中缀表达式串str1,转换为后缀表达式str2*/
IniStack(OPTR);
Push(OPTR, ′#′);
i=0;k=0;
while(str1[i]!=′#′||GetTop(OPTR)!=′#′)
{if(str1[i]>=′0′&&c<=′9′)
str2[k++]=str1[i++];/*数复制到str2中*/
else
{ if judge(str1[i]) return ERROR;
/* 判断是否操作符,若不是结束*/
switch(Precede(GetTop(OPTR),str[i])
/*比较操作符优先级高低*/
{ case ′<′:
/*栈顶优先级时str1[i]低直接复制到str2[k]中*/
str2[k++]=str1[i++];break;
case ′=′:/*优先级相等脱括号并处理下一个字符*/
Pop(OPTR,x);i++;break;
case ′>′:/*栈顶优先级高,将栈顶复制到str2中*/
Pop(OPTR,theta);
str2[k++]=theta; break;
}
}
}
return OK;/*正确返回*/
}。

相关文档
最新文档