1.需求和规格说明(问题描述)
描述问题,简述题目要解决的问题是什幺,规定软件做什幺,原题条件不足时要补全。
2.分析与设计思想(分析要处理的数据、主要和重点操作定义和概要算法)
3.分析问题的数据间的逻辑关系、说明所要采用的存储结构和要实现的操作。
4.定义数据类型(说明含义)
5.定义除基本算法之外的算法(要有每个算法的功能描述、接口参数说明、主要的处理、流程图或N-S图)
6.使用说明。
7.调试报告:测试用例,测试结果,调试过程中遇到的主要问题是如何解决的;对设计和编码的回顾讨论和分析;改进设想;经验和体会等。
8.附录:源程序清单和结果。程序要加注释,有较好的风格(可不打印、不上交);测试数据及输出结果。
表达式求值
1.需求分析
设计一个程序,演示用算符优先法对算术表达式求值的过程。利用算符优先关系,实现对算术四则混合运算表达式的求值。
(1)输入的形式:表达式,例如2*(3+4)
    包含的运算符只能有'+' 、'-' 、'*' 、'/' 、'('、 ')';
(2)输出的形式:运算结果,例如2*(3+4)=14;
(3)程序所能达到的功能:对表达式求值并输出
2.系统设计
1.栈的抽象数据类型定义:
ADT Stack{
数据对象:D={ai|ai∈ElemSet,i=1,2,…,n,n≥0}
数据关系:R1={<ai-1,ai>|ai-1,ai∈D,i=2,…,n}
          约定an端为栈顶,ai端为栈底
基本操作
Push(&S,e)
初始条件:栈S已存在
操作结果:插入元素e为新的栈顶元素
Pop(&S,&e)
初始条件:栈S已存在且非空
操作结果:删除S的栈顶元素,并用e返回其值
}ADT Stack
2.主程序的流程:
EvaluateExpression()函数实现了对表达式求值的功能,main()函数直接调用EvaluateExpression()对输入的表达式求值输出
函数的调用关系图:
3.各个模块的主要功能:
字符串拷贝函数strcpy作用
*Push(SC *s,char c):把字符压栈
*Push(SF *s,float f):把数值压栈
*Pop(SC *s):把字符退栈
*Pop(SF *s):把数值退栈
Operate(a,theta,b):根据theta对a和b进行'+' 、'-' 、'*' 、'/' 、'^'操作
In(Test,*TestOp):若Test为运算符则返回true,否则返回false
ReturnOpOrd(op,*TestOp):若Test为运算符,则返回此运算符在数组中的下标
precede(Aop,Bop):根据运算符优先级表返回Aop与Bop之间的优先级
EvaluateExpression(*MyExpression):用算符优先法对算术表达式求值
3.调试分析
(1)刚开始只编写了一个Push和一个Pop函数,但因为在EvacuateExpression()里既有运算符入/出栈,又有运算数入/出栈,运行下来总是出错。所以就编写了两个不同的Push和Pop函数,分别使用。
4.测试结果
输入表达式:2+3*4/5-1
输入表达式:5*(10-2*3)-8
输入表达式:(5-17)/3+2
5.用户手册
输入语法正确的、不含变量的数学表达式(运算符只能是'+' 、'-' 、'*' 、'/' 、'('、 ')'),回车即输出结果。
6.附录
源程序:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define true 1
#define false 0
#define OPSETSIZE 8
typedef int Status;
unsigned char Prior[8][8] = { // 运算符优先级表
    // '+' '-' '*' '/' '(' ')' '#' '^'
/*'+'*/'>','>','<','<','<','>','>','<',
/*'-'*/'>','>','<','<','<','>','>','<',
/*'*'*/'>','>','>','>','<','>','>','<',
/*'/'*/'>','>','>','>','<','>','>','<',
/*'('*/'<','<','<','<','<','=',' ','<',
/*')'*/'>','>','>','>',' ','>','>','>',
/*'#'*/'<','<','<','<','<',' ','=','<',
/*'^'*/'>','>','>','>','<','>','>','>'
};
typedef struct StackChar{
char c;
struct StackChar *next;
}SC; //StackChar类型的结点SC
typedef struct StackFloat{
float f;
struct StackFloat *next;
}SF; //StackFloat类型的结点SF
SC *Push(SC *s,char c){ //SC类型的指针Push,返回p
SC *p=(SC*)malloc(sizeof(SC));
p->c=c;
p->next=s;
return p;
}
SF *Push(SF *s,float f){ //SF类型的指针Push,返回p
SF *p=(SF*)malloc(sizeof(SF));
p->f=f;
p->next=s;
return p;
}
SC *Pop(SC *s){ //SC类型的指针Pop
SC *q=s;
s=s->next;
free(q);
return s;
}
SF *Pop(SF *s){ //SF类型的指针Pop
SF *q=s;
s=s->next;
free(q);
return s;
}
float Operate(float a,unsigned char theta, float b){ //计算函数Operate
switch(theta){
case '+': return a+b;
case '-': return a-b;
case '*': return a*b;
case '/': return a/b;
case '^': return pow(a,b);
default : return 0;
}
}
char OPSET[OPSETSIZE]={'+','-','*','/','(',')','#','^'};
Status In(char Test,char *TestOp){
int Find=false;
for (int i=0; i< OPSETSIZE; i++){
if (Test == TestOp[i]) Find= true;
}
return Find;
}
ReturnOpOrd(char op,char *TestOp){
for(int i=0; i< OPSETSIZE; i++)
if (op == TestOp[i]) return i;
}
char precede(char Aop, char Bop){
return Prior[ReturnOpOrd(Aop,OPSET)][ReturnOpOrd(Bop,OPSET)];
}
float EvaluateExpression(char* MyExpression){
// 算术表达式求值的算符优先算法
// 设OPTR和OPND分别为运算符栈和运算数栈,OP为运算符集合
SC *OPTR=NULL; // 运算符栈,字符元素
SF *OPND=NULL; // 运算数栈,实数元素
char TempData[20];
float Data,a,b;
char theta,*c,x,Dr[]={'#','\0'};
OPTR=Push(OPTR,'#');
c=strcat(MyExpression,Dr);

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。