数据结构与算法课内实验实验报告.docx
- 文档编号:11349790
- 上传时间:2023-02-28
- 格式:DOCX
- 页数:20
- 大小:724.96KB
数据结构与算法课内实验实验报告.docx
《数据结构与算法课内实验实验报告.docx》由会员分享,可在线阅读,更多相关《数据结构与算法课内实验实验报告.docx(20页珍藏版)》请在冰豆网上搜索。
数据结构与算法课内实验实验报告
数据结构与算法课内实验实验报告
实验报告
一、实验任务
实验题目:
数据结构与算法课内实验
二、实验内容
实验背景:
利用数据结构的知识分析鼠标操作者的鼠标行为,评价鼠标的操作效率,比如最大移动速度、平均移动速度等。
实验一文件读取和数据处理
(一)实验目的:
综合运用数据结构所学知识,掌握抽象数据类型的定义方法以及文件操作。
(二)基本要求:
读取文本文件数据,自定义合适的抽象数据类型按照要求存储数据,并实现下述要求。
(三)内容提要:
1、数据采集
本次实验,每位同学对自己采集到的数据进行处理。
数据采集的要求如下:
1)采集时间:
(1)11.15~11.16(数据结构专题实验第4次实验);
(2)11.24(第11周周末);
(3)第5次数据结构专题实验时间;
(4)课内实验验收时间待定
2)采集地点:
西一楼307;
3)采集时长:
每位同学5~10分钟;
4)采集内容:
每位同学认真完成指定的鼠标操作,包括鼠标的移动、鼠标单击和鼠标双击(见下述提示1)。
2、数据处理
采集到的数据会以文本的形式保存,一个文本文件称为一个样本。
每位同学需要m个样本完成实验。
读取文本文件并对数据进行如下操作:
1)自定义合适的数据结构类型保存读取到的数据,以方便后续的数据处理(原始数据格式见下述提示);
2)对一个样本中的数据按照鼠标操作的事件类型(单击和双击)进行切分,一个样本中的数据可以切分为16段(鼠标事件类型的定义见下述提示);
3)对于每段数据,如果出现时间戳重复的点,保留第一个点,删掉后面的重复点;
4)删除掉时间戳重复的点之后,对于每段数据进行如下计算:
(1)移动持续时间、
(2)移动速度序列、(3)移动加速度序列、(4)平均速度(计算方法见下述提示),自定义一个合适的数据结构类型保存上述4种数据,以方便后续的数据处理。
比如定义一个结构体,那么结构体中包含4项分别对应上述计算的4种类型的数据。
实验二数据排序和查找
(一)实验目的:
综合运用数据结构所学知识,掌握抽象数据类型的定义方法,熟悉并熟练运用查找、排序算法以及文件操作。
(二)基本要求:
自定义合适的抽象数据类型存储数据,并实现下述要求的查找和排序功能。
(三)内容提要:
1、数据处理
1)数据处理的过程在第一次实验数据处理的基础上继续进行;经过实验一中1)~4)数据处理之后,对于每个样本,数据被分为16段,每段数据有一个数据结构实体存储本段的段ID和4)中计算得到的4个变量:
(1)移动持续时间、
(2)移动速度序列、(3)移动加速度序列、(4)平均速度。
2)对于每段移动,计算平均速度在m个样本上的速度平均值,16段移动可以得到16个速度平均值,对这16个速度平均值进行排序,给出最大和最小速度对应的段ID和平均速度。
3)对于每段移动,计算移动持续时间在m个样本上的移动持续时间平均值,16段移动可以得到16个移动持续时间平均值,对这16个移动持续时间平均值进行排序,给出最长和最短移动持续时间对应的段ID和移动持续时间。
实验提示
1.鼠标操作示意图
16段移动,其中,前8段移动以鼠标单击为分割点,后8段移动以鼠标双击为分割点。
fig1鼠标操作示意图
2.原始鼠标数据格式
文本文件中的数据分多行保存,每一行的数据有4个维度,数据格式为
(鼠标操作类型、x坐标、y坐标、时间戳)
table1鼠标操作类型
鼠标操作类型
数值(十进制)
初始状态
512
移动或静止
512
左键按下
513
左键放开
514
eg:
鼠标操作类型x坐标y坐标时间戳
512,570,372,5724860移动起始点
............移动持续中
512,575,372,5724884移动终止点
513,576,372,5724796分割点
512,576,372,5724818点击时间间隔
514,576,372,5724884分割点
3.第i点速度计算:
如果x轴速度大于y轴速度,那么第i点的速度等于x轴速度;
如果y轴速度大于x轴速度,那么第i点的速度等于y轴速度。
对于每段第一个点,当i=1的时候,i-1等于0,所以第一点的速度记为0。
4.第i点加速度计算:
对于每段第一个点当i=1的时候,i-1等于0,所以第一个点的加速度记为0。
5.移动持续时间:
对于每段移动,移动结束点的时间戳减去移动起始点的时间戳。
6.平均速度
每一段的平均速度等于该段每一点的速度值之和与该段总点数的比值。
三、要点分析
题目中涉及的主要知识点:
1、抽象数据结构类型的定义及使用。
分别定义了四个数据结构类型structRecord(每条记录的存储结构)、structSample(每个样本(文件)的存储结构)structData(读取原始数据时的中间存储结构)structResult(统计结果的存储结构)。
2、文件的基本操作。
文件的打开及读取数据,写入数据等。
3、排序算法。
对得到的结果进行排序,得到最大最小值。
4、建立哈希函数进行查找操作。
四、程序的算法描述
1、所用存储结构:
typedefstructRecord//每条记录的存储结构
{
intID;//记录的ID号
intinterval;//每段记录的移动时间
floatv[100];//每段记录的速度序列
floata[100];//每段记录的加速度序列
floataverage;//每段的平均速度
}Record;
typedefstructSample//每个样本(文件)的存储结构
{
charfilename[40];//文件名
Recordrecord[16];//文件中的十六段记录
}Sample;
typedefstructData//读取原始数据时的中间存储结构
{
intx;//x坐标
inty;//y坐标
inttime;//时间戳
inttype;//操作类型
}Data;
typedefstructResult//统计结果的存储结构
{
intID;//每段的ID
floataverage_v;//每段在m个文件上的平均速度
intaverage_interval;//每段在m个文件上的平均移动时间
}Result;
2、程序中各函数的简要说明:
(1)voidstatistic(Sample*sample,intm)统计函数,将m个文件的原始数据读入并进行初步处理。
借助于data[0]、data[1]俩个数据交替读入文件内容,根据数据的操作类型执行不同的操作。
若是512,则进行速度、加速度的计算及移动时间的累加;若是513、514,则进行数据的切分。
在对数据进行统计的同时,将统计结果写入文件“log1.txt”中。
(2)voidanalyse(Resultresult[16],Sample*sample,intm)分析函数。
求出各项数据在m个文件上的平均值,并利用冒泡法进行排序,将排序结果结最大最小值写入文件“log2.txt”中。
(3)intmain()主函数:
调用statistic(sample,m);analyse(result,sample,m);统计数据并实现查询功能。
由输入要查找的ID号,用哈希函数计算的相应的存储地址,得到查询结果。
3、源代码
完整程序及相应说明如下:
#include"stdio.h"
#include"stdlib.h"
#include"malloc.h"
#include"math.h"
#include"string.h"
typedefstructRecord//每条记录的存储结构
{
intID;//记录的ID号
intinterval;//每段记录的移动时间
floatv[100];//每段记录的速度序列
floata[100];//每段记录的加速度序列
floataverage;//每段的平均速度
}Record;
typedefstructSample//每个样本(文件)的存储结构
{
charfilename[40];//文件名
Recordrecord[16];//文件中的十六段记录
}Sample;
typedefstructData//读取原始数据时的中间存储结构
{
intx;//x坐标
inty;//y坐标
inttime;//时间戳
inttype;//操作类型
}Data;
typedefstructResult//统计结果的存储结构
{
intID;//每段的ID
floataverage_v;//每段在m个文件上的平均速度
intaverage_interval;//每段在m个文件上的平均移动时间
}Result;
voidstatistic(Sample*sample,intm)//统计函数,将m个文件的原始数据读入并进行初步处理
{
FILE*fp;
FILE*fpp;
if((fpp=fopen("log1.txt","w"))==NULL)
{printf("无法打开文件");return;}
inti,j,k=0;
Datadata[2];//俩个原始数据单元,交替读入数据
for(i=0;i { while((fp=fopen(sample[i].filename,"r"))==NULL)//打开文件,若文件无法打开,重新输入 { printf("无法打开第%d个文件,请重新输入\n",i+1); scanf("%s",sample[i].filename); } fprintf(fpp,"第%d个文件的文件名: %s\n",i+1,sample[i].filename); fscanf(fp,"%d%d%d%d",&data[0].type,&data[0].x,&data[0].y,&data[0].time); for(j=0;j<16;j++) { floatsum=0; intcount=0; for(k=0;k<100;k++)//现将所有的速度初值赋值为最大 {sample[i].record[j].v[k]=sample[i].record[j].a[k]=300000000;} k=0; sample[i].record[j].ID=(i+1)*100+j+1;//产生每段的ID,百位代表文件号,十位和个位代表第几段 sample[i].record[j].interval=data[0].time; while(! feof(fp)) { fscanf(fp,"%d%d%d%d",&data[1].type,&data[1].x,&data[1].y,&data[1].time); while(data[0].time==data[1].time)//若时间戳相同,则重新读入 {fscanf(fp,"%d%d%d%d",&data[1].type,&data[1].x,&data[1].y,&data[1].time);} if(data[1].type==513){k=0;break;}//若遇到513,代表该段结束,进入下一段的统计 if(abs(float(data[0].x-data[1].x)/float(data[0].time-data[1].time))>abs(float(data[0].y-data[1].y)/float(data[0].time-data[1].time))) { sample[i].record[j].v[k]=float(data[0].x-data[1].x)/float(data[0].time-data[1].time); sample[i].record[j].a[k]=sample[i].record[j].v[k]/(data[1].time-data[0].time); sum=sum+sample[i].record[j].v[k]; k++; count++; } else { sample[i].record[j].v[k]=(float(data[0].y-data[1].y)/float(data[0].time-data[1].time)); sample[i].record[j].a[k]=sample[i].record[j].v[k]/(data[1].time-data[0].time); sum=sum+sample[i].record[j].v[k]; k++; count++; } data[0]=data[1]; } sample[i].record[j].interval=data[1].time-sample[i].record[j].interval; sample[i].record[j].average=sum/float(count); fprintf(fpp,"第%d个样本的第%d个记录的ID: %d\n",i+1,j+1,sample[i].record[j].ID);//将处理结果写入文件中 fprintf(fpp,"第%d个样本的第%d个记录的移动持续时间: %d\n",i+1,j+1,sample[i].record[j].interval); fprintf(fpp,"第%d个样本的第%d个记录的平均速度: %f\n",i+1,j+1,sample[i].record[j].average); fprintf(fpp,"第%d个样本的第%d个记录的速度及加速度序列: \n\tv\t\ta\n",i+1,j+1); for(k=0;k<100;k++) { if(sample[i].record[j].v[k]==300000000)break; fprintf(fpp,"%9.6f\t%9.6f\n",sample[i].record[j].v[k],sample[i].record[j].a[k]); } if(data[1].type==513)//对文件进行切分 { fscanf(fp,"%d%d%d%d",&data[0].type,&data[0].x,&data[0].y,&data[0].time); while(data[0].type==512){fscanf(fp,"%d%d%d%d",&data[0].type,&data[0].x,&data[0].y,&data[0].time);} fscanf(fp,"%d%d%d%d",&data[0].type,&data[0].x,&data[0].y,&data[0].time); if(data[0].type==513) { fscanf(fp,"%d%d%d%d",&data[0].type,&data[0].x,&data[0].y,&data[0].time); while(data[0].type==512){fscanf(fp,"%d%d%d%d",&data[0].type,&data[0].x,&data[0].y,&data[0].time);} fscanf(fp,"%d%d%d%d",&data[0].type,&data[0].x,&data[0].y,&data[0].time); } continue; } } } fclose(fp); fclose(fpp); printf("原始数据读入成功,已存入log1.txt\n"); } voidanalyse(Resultresult[16],Sample*sample,intm)//分析函数。 求出各项数据在m个文件上的平均值,并排序 { inti,j,k; intsum_time; floatsum_v; Resulttemp; FILE*fpp; if((fpp=fopen("log2.txt","w"))==NULL) {printf("无法打开文件");return;} for(j=0;j<16;j++)//对16段上的数据在m个文件上求平均值 { sum_time=0; sum_v=0.0; for(i=0;i { sum_time+=sample[i].record[j].interval; sum_v+=sample[i].record[j].average; } result[j].ID=j+1; result[j].average_interval=sum_time/m; result[j].average_v=sum_v/float(m); } fprintf(fpp,"按移动时间由小到大排序: \nID、移动时间、平均速度: \n"); for(i=0;i<16;i++)//对16个数据用冒泡法按时间进行排序 { for(j=0;j<15-i;j++) { if(result[j].average_interval<=result[j+1].average_interval) {temp=result[j];result[j]=result[j+1];result[j+1]=temp;} } fprintf(fpp,"%2d\t%4d\t\t%9.6f\n",result[15-i].ID,result[15-i].average_interval,result[15-i].average_v); } fprintf(fpp,"最大移动时间段的信息: \n%d\t%d\t\t%9.6f\n",result[0].ID,result[0].average_interval,result[0].average_v); fprintf(fpp,"最小移动时间段的信息: \n%d\t%d\t\t%9.6f\n\n",result[15].ID,result[15].average_interval,result[15].average_v); fprintf(fpp,"按平均速度由小到大排序: \nID、移动时间、平均速度: \n"); for(i=0;i<16;i++)//对16个数据用冒泡法按时间进行排序 { for(j=0;j<15-i;j++) { if(abs(result[j].average_v)<=abs(result[j+1].average_v)) {temp=result[j];result[j]=result[j+1];result[j+1]=temp;} } fprintf(fpp,"%2d\t%4d\t\t%9.6f\n",result[15-i].ID,result[15-i].average_interval,result[15-i].average_v); } fprintf(fpp,"最大平均速度段的信息: \n%d\t%d\t\t%9.6f\n",result[0].ID,result[0].average_interval,result[0].average_v); fprintf(fpp,"最小平均速度段的信息: \n%d\t%d\t\t%9.6f\n\n",result[15].ID,result[15].average_interval,result[15].average_v); fclose(fpp); printf("数据分析完成,排序结果已存入log2.txt\n"); } intmain()//主函数: 调用statistic(sample,m);analyse(result,sample,m);统计数据并实现查询功能 { inti,m,id,flag; charstring[4]; Resultresult[16]; printf("请输入要分析的文件个数: "); scanf("%d",&m); Sample*sample; sample=(Sample*)malloc(m*sizeof(Sample));//创建m个文件的存储空间 for(i=0;i { printf("请输入第%d个文件的文件名: ",i+1); scanf("%s",sample[i].filename); } statistic(sample,m); analyse(result,sample,m); printf("是否要进行查找操作? YESorNO: ");//实现查找功能 scanf("%s",string); while(! strcmp(string,"YES")) { flag=1; while(flag) { printf("请输入要查找的ID号: "); scanf("%d",&id); for(i=0;i {if(id>=(i*100+101)&&id<=(i*100+116))flag=0;} if(id>=1&&id<=16)flag=0; if(flag)printf("输入错误\n"); } printf("查找结果: \n"); if(id/100) {printf("%s\t%d\t%d\t%9.6f\n",sample[id/100-1].filename,sample[id/100-1].record[id%100-1].ID,sample[id/100-1].record[id%100-1].interval,sample[id/100-1].record[id%100-1].average);} else { for(i=0;i<16;i++) {if(result[i].ID==id)break;} printf("%d\t%d\t%9.6f\n",result[i].ID,result[i].average_interval,result[i].average_v);} printf("是否继续: YESorNO? "); scanf("%s",string); } printf("Thanks...\n"); r
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 算法 实验 报告