计算机基础算法实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算机基础算法实验报告
班级:
学号:
姓名:
指导教师:
完成日期:
实验一实现两个整数相加
1.实验任务
实现两个长整数相加:要求用链表(单链表或双向链表)实现任意位数的整数相加。
2.设计思想
用单链表实现两个任意位整型相加,建立三个动态链表,两个分别用来存入两个加数,第三个链表用来存入和。
考虑到进位以及算术加法习惯,采用逆序插入节点,先存高位再存低位数,头指针指向最后插入的节点。
进行相加后存入第三个链表,最后将结果输出。
3.主要变量说明
data 链表结点的数据域
*next 链表结点的指针
node单链表类型
*list 单链表类型指针
head 指向链表的头指针
l3 指向第三个链表的头指针
j 进位标志
4.算法描述
首先定义单链表的结构体类型,然后输入两个数,调用创建链表函数创建两个单链表将输入的数分别依次逆序存入,高位存入第一个结点,低位存入之后的结点,最后的结点存个位,并不断循环始终使头指针指向新插入的结点。
然后调用相加函数,并动态创建第三个链表将结果仍逆序存入第三个链表中。
最后调用输出函数将结果输出。
5.程序结构
List creat()
操作结果:构造一个动态链表
list add(list l1,list l2)
初始条件:链表l1,l2已存在
操作结果:将两个链表的数据依次对应相加,并将结果倒叙存入
链表l3
void out(list l)
初始条件:链表已存在
操作结果:依次输出链表中的数据
主函数:
void main()
{
list l1,l2,l3;
printf("请输入第一个整数,末尾输入-1表结束: ");
l1=creat();
out(l1);
printf("请输入第二个整数,末尾输入-1表结束: ");
l2=creat();
out(l2);
printf(”相加结果为: ”);
l3=add(l1,l2);
out(l3);
}
6.运行结果
请输入第一个整数,末尾输入-1表结束:1 2 3 4 -1
4321
请输入第二个整数,末尾输入-1表结束:7 8 9 -1
987
相加结果为:2023
7.心得体会
通过本次编写程序,我对单链表有了更深的理解,由于没有使用双向链表,就采取了逆向插入结点,这使我对逆向插入有更深的理解。
正向插入节点需要两个指针来完成插入结点,头指针位置不动,而逆向插入头指针永远指向新插入的结点,这就省去了一个指针,用头指针代替。
8.程序清单
#include<stdio.h>
#include<malloc.h>
#define len sizeof(node)
typedef struct node
{
int data;
struct node *next;
}node,*list;
list creat()
{
node *head;
node *p1,*p2;
p1=p2=(list)malloc(len);
scanf("%d",&p1->data);
head=NULL;
while(p1->data!=-1)
{
p1->next=head; head=p1;
p1=(node*)malloc(sizeof(node));
scanf("%d",&p1->data);
}
return(head);
}
list add(list l1,list l2)
{
node *p1,*p2,*p3,*l3; l3=NULL;
int sum=0;
int j=0;//定义进位标志
p1=l1;
p2=l2;
while(p1&&p2)
{
p3=(list)malloc(len);
sum=p1->data+p2->data+j;
if(sum>9)
{
p3->data=sum-10;
j=1;
}
else if(sum>=0&&sum<10)
{
p3->data=sum;
j=0;
}
p1=p1->next;
p2=p2->next;
p3->next=l3;
l3=p3;
}
while(p1)
{
p3=(list)malloc(len);
sum=p1->data+j;
if(sum>9)
{
p3->data=sum-10;
j=1;
}
else if(sum>=0&&sum<10) {
p3->data=sum;
j=0;
}
p1=p1->next;
p3->next=l3;
l3=p3;
}
while(p2)
{
p3=(list)malloc(len);
sum=p2->data+j;
if(sum>=10)
{
p3->data=sum-10;
j=1;
}
else if(sum>=0&&sum<10) {
p3->data=sum;
j=0;
}
p2=p2->next;
p3->next=l3;
l3=p3;
}
if(j)
{
p3=(list)malloc(len);
p3->data=1;
p3->next=l3;
l3=p3;
}
//head=l3;
return(l3);
}
void out(list l)
{
node *p;
p=l;
while(p)
{
printf("%d",p->data);
p=p->next;
}
printf("\n");
}
void main()
{
list l1,l2,l3;
printf("请输入第一个整数,末尾输入-1表结束: ");
l1=creat();
out(l1);
printf("请输入第二个整数,末尾输入-1表结束: ");
l2=creat();
out(l2);
printf(”相加结果为: ”);
l3=add(l1,l2);
out(l3);}
实验二:算术表达式求值.
1.实验任务
以字符序列的形式从终端输入语法正确的,不含变量的整数表达式,利用给定的算符优先关系,实现对算术四则混合运算表达式的求值,并演示在求值过程中运算符栈,操作数栈,操作数栈和主要操作的变化过程。
分析:
(1)输入要求:以字符序列的形式输入不含变量的表达式(表达式中的整数可以是多位的)。
(2)演示要求:求值过程中利用到运算符栈,操作数栈。
(3)程序所达到的功能:利用给定的算符优先关系,通过栈实现算数四则混合运算表达式求值。
2.设计思想
将表达式按顺序输入并进栈,有运算符栈和运算数栈两种,利用函数判断是否为运算符,若为运算符则转换为实数并入栈,第一个整数为栈底,最后一个整数为栈顶,输入#表示输入结束。
利用栈顶指针进行出栈,用函数判断是否为运算符,若为运算符由给出的运算符优先级关系进行表达式计算,结果仍进栈,再进行比较、计算,直到最后计算出一个实数,最后与#比较再出栈即为表达式求值结果。
3.算法描述
(1)定义两个指针top base
(2)屏幕输出:请输入表达式:(end #):输入任意的数并调用template <typename T> struct SqStack和template <typename T1,typename T2> Status Push(T1 &S,T2 e)使表达式入栈。
(3)调用函数Status In(char Test,char* TestOp)使运算符入栈。
(4)调用函数float Operate(float a,unsigned char theta, float b)和switch (precede(GetTop<SqStack<char>,char>(OPTR), c))进行判断并计算表达式。
(5)调用关系:主函数void main()调用函数EvaluateExpression
4. 程序结构
template <typename T> struct SqStack
操作结果:创建顺序栈结构模板。
template <typename T1,typename T2> Status InitStack(T1 &S)
操作结果:初始化栈模板。
template <typename T1,typename T2> Status Push(T1 &S,T2 e)
操作结果:表达式入栈。
template <typename T1,typename T2> Status Pop(T1 &S,T2 &e) 操作结果:表达式出栈。
template <typename T1,typename T2> T2 GetTop(T1 S)
操作结果:获取栈顶元素。
Status In(char Test,char* TestOp)
操作结果:判断是否为运算符。
float Operate(float a,unsigned char theta, float b)
操作结果:运算。
switch (precede(GetTop<SqStack<char>,char>(OPTR), c))
操作结果:判断并进行出栈运算。
主函数
void main()
{
printf("请输入表达式(end #):\n");
printf("结果为%d\n",EvaluateExpression());
}
5.运行结果请输入表达式(end#):1+2*3—6/3+(3+2)*3 #
结果为:20.
6.心得体会
通过本次程序编写,我对栈以及利用栈进行算术表达式的求值的认识有了提高。
我体会到了编写程序需要耐心和细心,少加或多加一个括号都会导致程序出错。
要把算法付诸于程序,需要不断调试并修改。
7.程序清单
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define error 0
#define ok 1
#define overflow -1
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define OPSETSIZE 7
char OPSET[OPSETSIZE]={'+','-','*','/','(',')','#'}; unsigned char Prior[7][7] = { // 算符间的优先关系'>','>','<','<','<','>','>',
'>','>','<','<','<','>','>',
'>','>','>','>','<','>','>',
'>','>','>','>','<','>','>',
'<','<','<','<','<','=',' ',
'>','>','>','>',' ','>','>',
'<','<','<','<','<',' ','='
};
typedef int Status;
template <typename T>
struct SqStack
{
T *top;
T *base;
int stacksize;
};//顺序栈结构模板
template <typename T1,typename T2>
Status InitStack(T1 &S)
{
S.base=(T2 *)malloc(STACK_INIT_SIZE*sizeof(T2)); if(!S.base) exit (overflow);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return ok;
}//初始化栈函数模板
template <typename T1,typename T2>
Status Push(T1 &S,T2 e)
{
if(S.top-S.base>=S.stacksize)
{
S.base=(T2
*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(T2));
if(!S.base) exit (overflow);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
return ok;
}//入栈函数模板
template <typename T1,typename T2>
Status Pop(T1 &S,T2 &e)
{
if(S.top==S.base) return error;
e=*--S.top;
return ok;
}//出栈函数模板
template <typename T1,typename T2>
T2 GetTop(T1 S)
{
if(S.top==S.base)
return error;
else
return *(S.top-1);
}//获取栈顶元素模板
Status In(char Test,char* TestOp) {
bool Find=false;
for (int i=0; i< OPSETSIZE; i++) {
if (Test == TestOp[i]) Find= true;
}
return Find;
}//判断是否为运算符
float Operate(float a,unsigned char theta, float b) {
switch(theta) {
case '+': return a+b;
case '-': return a-b;
case '*': return a*b;
case '/': return a/b;
default : return 0;
}
}//运算
int ReturnOpOrd(char op,char* TestOp) {
int i;
for(i=0; i< OPSETSIZE; i++) {
if (op == TestOp[i]) return i;
}
return 0;
}
char precede(char Aop, char Bop) {
return Prior[ReturnOpOrd(Aop,OPSET)][ReturnOpOrd(Bop,OPSET)];
}//ReturnOpOrd和precede组合,判断运算符优先级
float EvaluateExpression() {
// 算术表达式求值的算符优先算法。
// 设OPTR和OPND分别为运算符栈和运算数栈,OPSET为运算符集合。
SqStack<char> OPTR; // 运算符栈,字符元素
SqStack<float> OPND; // 运算数栈,实数元素
char TempData[20];
float Data,a,b;
char theta,c,x,Dr[2];
InitStack<SqStack<char>,char> (OPTR);
Push (OPTR, '#');
InitStack <SqStack<float>,float>(OPND);
strcpy(TempData,"\0");//将TempData置为空
c=getchar();
while (c!= '#' || GetTop<SqStack<char>,char>(OPTR)!= '#')
{
if (!In(c, OPSET))
{
Dr[0]=c;
Dr[1]='\0';//存放单个数
strcat(TempData,Dr);//将单个数连到TempData中,形成字符串
c=getchar();
if(In(c,OPSET))//如果遇到运算符,则将字符串TempData转换成实数,入栈,
并重新置空
{
Data=(float)atof(TempData);
Push(OPND, Data);
strcpy(TempData,"\0");
}
}
else
{ // 不是运算符则进栈
switch (precede(GetTop<SqStack<char>,char>(OPTR), c)) {
case '<': // 栈顶元素优先权低
Push(OPTR, c);
c=getchar();
break;
case '=': // 脱括号并接收下一字符
Pop(OPTR, x);
c=getchar();
break;
case '>': // 退栈并将运算结果入栈
Pop(OPTR, theta);
Pop(OPND, b);
Pop(OPND, a);
Push(OPND, Operate(a, theta, b));
break;
} // switch
}
} // while
return GetTop<SqStack<float>,float>(OPND); } // EvaluateExpression
void main()
{
printf("请输入表达式(end #):\n");
printf("结果为%d\n",EvaluateExpression());
}。