计算机基础算法实验报告

  • 格式:doc
  • 大小:82.50 KB
  • 文档页数:13

计算机基础算法实验报告班级:08计算机7班学号:0813********姓名:许可完成日期:2009年11月28日实验一:实现两个整数相加1、需求分析:要求用链表(单链表或双向链表)实现任意位数的整数相加(1)输入的形式和输入值的范围:输入任意长度的正整数,回车,再输入任意整数,即可得出结果。

范围是零到正无穷。

(2)输出的形式:以正整数形式输出。

(3)程序所能达到的功能:以链表形式实现任意位数的正整数相加。

(4)测试数据:①正确结果:输入1234567890123456789再输入9876543210987得出结果1234577766666667776.②错误结果:输入-789,再输入78994456 得出789952452、概要设计:(1)抽象数据类型ADT LNode{数据元素:此单向链表中的所有元素类型为字符型的数字字符数据关系:链表中数据元素之间是线性关系。

基本操作:LNode *creat(void)操作结果:创建一个单向链表,并且逆序输入链表元素基本操作:void print(LNode *head)操作结果:输出单向链表基本操作:LNode *Creat(LNode *head1,LNode *head2)操作结果:对两个链表进行相加操作,建立相加后的链表}ADT LNode(2)主程序操作流程:定义三个指针变量head1 head2 head3屏幕输出:Please enter the first number:输入任意位数数字,调用LNode *creat(void),建立链表head1屏幕输出:Please enter the second number:输入任意位数数字,调用LNode *creat(void),建立链表head2调用函数Creat(head1,head2)对链表head1,head2进行相加操作,建立新链表head3调用函数print(head3)输出链表head3屏幕输出:The num is:”head3”程序结束(3)调用关系:主函数void main()可调用子函数creat(void)以及子函数Creat(head1,head2)以及子函数print(LNode *head)3、详细设计(1)此算法的基本思想:首先创建逆序链表1,即将输入的数字逆序进入链表,再创建链表2,将输入的数字逆序进入链表。

此时两个链表的头节点的下一个节点均对应为数字的个位数,再对两个链表进行相加操作,分别从两个链表的头节点的下一节点进行两两相加,相加结果临时存入num变量,并且放置整型变量carry储存进位,进行num对10求余,余数存入节点p,carry为整型变量,对carry进行相加结果/10操作,若相加结果小于10,carry=0,若结果大于10,carry=1。

将相加结果存入新链表的头节点的下一节点,循环两个链表,直至两个链表循环结束。

此时新链表即为相加后的链表,理论可以实现任意位数的正整数相加。

(2)调用关系图:4、调试分析(1)测试数据:输入123456789123456789123456789123456789输入:987654321098765432109876543210输出结果:123457776777777887888888898999999999(2)时间复杂度分析:子程序LNode *creat(void)中有while((n=getchar())!='\n')循环语句,语句频度为n子程序void print(LNode *head)中有while(r->next!=NULL)循环语句,语句频度为n子程序LNode *Creat(LNode *head1,LNode *head2)中有while((r!=NULL)&&(s!=NULL))以及while(t!=NULL)两个循环语句,频度均为n所以此程序的时间复杂度为T(n)=O(n)(3)设计和调试时出现的问题:开始的时候编译好程序可以相加,但是只可以是两个数字位数对应且没有进位时结果正确,经检查是创建链表的时候是正序创建,相加是从头节点的下一节点也就是最高位开始相加,所以出现此错误。

后改正为逆序创建链表,测试后结果正确。

(4)算法的改进设想:可以增加分析输入数据正负的函数,并建立相关的负数相加,正负相加,负正相加等函数,实现程序可以进行任意位数的正负数相加的功能。

5、总结(1)实验的收获:通过对实验的思考以及编译过程,我可以对课本所学知识进行熟练运用,包括单链表的建立,正序逆序的分别,单链表的输出,两个单链表的操作,相加以及进位的算法思想的建立以及正确编译。

(2)实验重要性的认识:通过思考以及编译此实验,我认识到链表在程序编译过程中的重要以及便利性,而且通过对单链表的各种建立、输出、操作等过程的实现,进而可以对双链表、循环链表等形式的链表有一定的了解,可以举一反三,获取更多的知识。

实验的实际操作更让我强化了动手动脑能力,以及对程序编译过程中常见的错误的改正能力。

实验2:算术表达式求值1、需求分析:实验要求以字符序列的形式从终端输入语法正确的、不含变量的整数表达式,利用给定的算符优先关系,实现对算术四则混合运算表达式的求值,并演示在求值过程中运算符栈、操作数栈、操作数栈和主要操作的变化过程。

(1) 输入形式和输入值范围:正确输入算术表达式,包括+、-、*、/、(、)等正确的运算符,并且输入完毕后以#结尾。

输入值范围为正负整数,理论可计算100位数字,实际可计算11位数字的+、-、*、/以及()运算。

(2) 输出形式:计算结果整数六位及六位以内以整型输出,在六位以上以有效数字6位的科学计数法输出。

(3) 程序所能达到的功能:可以计算+、-、*、/以及括号运算,精度达到6位有效数字。

(4) 测试数据:①正确结果:输入1234+(6547-9874)/6321*314# 输出结果1068.73输入(123456789+987654321)*6478# 输出结果1.43956e+012②错误结果:输入214(321-897)(643*64)# 输出结果411522、概要设计(1)抽象数据类型ADT SqStack{数据类型:此链栈中的元素类型为字符型数字字符数据关系:栈中数据元素之间是线性关系。

基本操作:int InitStack(SqStack &S)操作结果:构造一个空栈基本操作:char GetTop(SqStack S,SElemType &e)操作结果:用e返回S的栈顶元素基本操作:int Push(SqStack &S,SElemType e)操作结果:插入元素e为新的栈顶元素基本操作:bool Pop(SqStack &S,SElemType &e)操作结果:删除S的栈顶元素,并用e返回其值}ADT SqStack(2)系统中子程序及功能要求:char Precede(char a,char b):比较两个运算符的优先级,a是栈顶字符,b是表达式字符。

SElemType Operate(SElemType a,SElemType b,SElemType c):解析表达式中的双目运算,其返回的结果即为双目运算表达式的值。

int In(char c):判断输入的字符是否为运算符。

SElemType EvaluateExpression():这是此程序的核心函数,可以综合其它子函数,实现最终的表达式求解。

(3)主程序的流程:定义SElemType型变量a,屏幕输出:请输入算术表达式(以#结束):调用SElemType EvaluateExpression()子程序,进行数栈与符栈的初始化以及入栈出栈、调用函数SElemType Operate(SElemType a,SElemType b,SElemType c)进行运算等核心操作,并且将程序返回值赋值给a,屏幕输出:结果是:”a”程序结束(4)调用关系:主函数int main()可调用子程序SElemType EvaluateExpression(),子程序SElemType EvaluateExpression()可调用模块int InitStack(SqStack &S),模块char GetTop(SqStack S,SElemType &e),模块int Push(SqStack &S,SElemType e),模块bool Pop(SqStack &S,SElemType &e),子程序char Precede(char a,char b),子程序SElemType Operate(SElemType a,SElemType b,SElemType c),子程序int In(char c)。

3、详细设计(1)此算法的基本思想:先定义数栈OPND和符栈OPTR,初始化两个栈,把’#’压入符栈底,获取栈顶元素用while判断若当前元素以及栈顶元素不是’#’,则执行下续循环:如果是属于运算符或者’0’到’9’的数字,再执行如下循环:赋值变量i=0;如果是数字,用atof()函数将数字压入栈顶;如果是运算符,调用char Precede(char a,char b)函数判断并返回当前运算符与栈顶预算符的优先值;当优先值是’<’,将当前运算符入栈,继续循环while判断;当优先值是’=’,将栈顶运算符出栈,继续循环while判断;当优先值是’>’,将栈顶运算符出栈,栈顶数字出栈,再栈顶数字出栈,调用SElemType Operate(SElemType a,SElemType b,SElemType c)对两数以及运算符进行双目运算,将运算结果压入数栈,继续while循环;如果既不是数字也不是运算符,那么输出错误信息。

遇到’#’则while循环结束,将数栈栈顶元素输出,即为结果。

(2)调用关系图:4、测试分析:(1)测试数据:输入1234+(6547-9874)/6321*314# 输出结果1068.73输入(123456789+987654321)*6478# 输出结果1.43956e+012(2)时间复杂度分析:在int In(char c)里有for(i = 0;i<7;i++)循环,频度为7;在SElemType EvaluateExpression()里,有while(c>='0'&&c<='9'),时间复杂度为n;所以此程序的时间复杂度T(n)=O(n)(3)设计和调试时存在的问题:模块之间的调用关系出现错误,比如GetTop()返回值出错导致程序循环错误,输出值始终为0。