网络152大数据处理.docx
《网络152大数据处理.docx》由会员分享,可在线阅读,更多相关《网络152大数据处理.docx(93页珍藏版)》请在冰豆网上搜索。
网络152大数据处理
课程设计报告
设计(论文)题目:
大数据处理
学院名称:
电子与信息工程学院
专业班级:
网络工程15-2班
成员姓名:
吴宏磊学号15401190222
成员姓名:
郑杨子学号15401190206
成员姓名:
蒋发明学号15401190214
指导教师:
盛啸涛
2016年1月6日
一、概述
1、实验内容
(1)读取文件中的密码(password)字段,统计密码出现的次数count,写入文件password.txt。
不需要排序。
格式:
每行一条记录,password和count中间用TAB分隔(即C语言中的\t)。
(ReadPassword)
(2)读取password.txt,对密码出现次数按照降序排序。
分别采用:
直接插入排序、希尔排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序、基数排序;求出每种排序方法所需要的绝对时间。
屏幕上输出各种各种排序的绝对时间。
最后屏幕上输出出现次数最多的20个密码及次数。
(RankTimePassword)
(3)读取user.txt,使用链表存放,使用顺序查找,随机生成2000个user_id(1~1,230,000之内的),再随机生成20个user_id(大于1,230,000的),输出查找所花总时间。
(SearchTimeNode)
(4)读取user.txt,按照用户id使用二叉排序树存放,随机生成2000个user_id(1~1,230,000之内的),再随机生成20个user_id(大于1,230,000的),输出查找所花总时间。
(SearchTimeTree)
(5)读取user.txt,先按照user_id排序,结果写入user_sorted.txt。
用不同的排序方法分别输出排序所需时间。
(如果所花时间过长,请缩小数据范围,并估算最终所需的大概时间)
(RankTimeId)
(6)读取user_sorted.txt,使用二分查找,随机生成2000个user_id(1~1,230,000之内的),再随机生成20个user_id(大于1,230,000的),输出查找所花总时间。
(只计算查找的时间)
(SearchTimeTwo)
(7)设计一个哈希存储的方案,用来存放password.txt中的数据(关键字为密码);设计20个存在的密码和不存在的密码,输出该密码和出现的次数,以及查找所花总时间。
(HaxiStore)
2、实验目的
通过数据结构课程设计,让我们了解8种排序的方法和运算时间,明白了大数据处理的方法,了解了哈希存储的方案以及所需查找的时间,利用二分查找随机产生的数据所需要的时间,通过这次实验,回顾了以前所学习的知识,更加掌握了数据结构的排序和算法。
3、组员权重:
蒋发明:
1.2
吴宏磊:
0.9
郑杨子:
0.9
二、系统设计
1、题目分析:
要求对大数据进行处理,每行包含一条记录,每条记录包含:
user_id和password中间为TAB分隔。
2、数据结构设计
3、程序流程图
文字描述:
主函数主要为while循环,对应的功能号进入对应的功能,0则退出循环,每个功能都是根据学期和班级来进入相应的数据文件。
4、详细设计
全局变量有intbehind,Termt1,t2,behind用于防止输出成绩单时将未录入的学生成绩输出
在程序中定义了三个类:
Term,Cls,Stu,运用到了类的嵌套,学生嵌套在班级中,班级嵌套在学期里,学生类中有许多函数用于实现某些功能。
在程序中还有readfile读文件函数和writetofile写文件函数,读文件函数设置为inline函数加快程序运行效率。
主函数主要为一个while循环,输入相应的功能号进入相应的函数功能模块,输入0为结束,在各个功能模块开始前都会进行一次读文件操作,进行处理后将修改或者录入的数据重新写入到文件中覆盖原有数据。
读写文件用到了fstream,istream和ostream。
文件为txt文件格式为term1_1.txt用于保存第一学期1班的成绩数据。
三、实验结果
四、实验总结
1、工作日志
日期
时间
内容
完成模块
12.26
13:
30-16:
30
整个程序的规划
完成文件的写入
12.27
13:
30-16:
30
了解前四个算法
完成前四个排序
12.28
13:
30-16:
30
了解后四个算法
完成后四个排序
12.29
13:
30-16:
30
了解链表存放
完成链表存放
12.30
13:
30-16:
30
了解二分查找
完成二分查找
1.03
13:
30-16:
30
了解哈希存储
完成哈希存储
1.04
13:
30-16:
30
答辩
程序的测试
2、实验心得
本次课程设计我们所设计的程序是大数据处理,在做本次设计前我们便对整体程序所需要的功能进行分类,按功能模块对程序功能进行实现,这让我们学到了在完成一个较大的程序时应该先进行策划,将大功能分解成一个个小功能,然后将小功能进行实现,最后整体整合寻找bug,进行修复。
另外我们还稍微了解了文件流的运用,以及用到了一些文件操作,写入和读出;我们还运用了类的嵌套,对数据进行更好的分类。
在完成这次课程设计中也遇到了一些问题:
对文件操作不够熟练,对文件流得概念不怎么了解,在进行编程时对程序结构设计的不够好,所以在寻找bug的时候太费劲,在调试程序是整体思路不够清晰,所以也浪费了大量时间,在编程中一些基本的语法也不够熟练,需要经常性的查阅书籍和上网。
当然,本次课程设计还是非常有益的,这锻炼了我们组员的团队合作能力,让我们了解,一个软件是需要许多人一起来完成,一起找bug,一起修复,也让我们认识到自己在编程方面的不足和需要改进的一些地方。
3、参考文献
C++文件读写详解(ofstream,ifstream,fstream):
c++读写文件流
C++学习笔记之对文件的操作
五、附件:
程序源码
#include
#include
#include
#include
#include
usingnamespacestd;
classUser
{
public:
User()
{
user_id=0;
password="";
count=0;
}
intuser_id;
stringpassword;
intcount;
~User(){}
};
typedefstructUserNode
{
UserNode()
{
userNode_id=0;
passwordNode="";
countNode=0;
nextNode=NULL;
}
intuserNode_id;
stringpasswordNode;
intcountNode;
structUserNode*nextNode;
}UserNode;
typedefstructnode
{
node()
{next=NULL;};
chardata[4];
structnode*next;
stringpassw;
}RecType1;
typedefstructnodeId
{
nodeId()
{next=NULL;};
chardata[7];
structnodeId*next;
stringpassw;
}RecType1Id;
structUserTree
{
UserTree()
{lchild=NULL;rchild=NULL;data=0;passw="";};
structUserTree*lchild,*rchild;
intdata;
stringpassw;
};
#defineIdNum25000
intfcount=0;//用于遍历用户
Useru[IdNum];//所有用户
UserNodeun[IdNum];
stringpassw[IdNum];//用于存放重复的密码
intpw=0;//用于确定放到passw数组中的序号
intstatus=0;//用于确定是否重复
//快速排序
voidQuickSort(Useru[],ints,intt)
{
inti=s,j=t;
inttemp;
stringtemp1;
if(s{
temp=u[s].count;//第1个元素作为基准
temp1=u[s].password;
while(i!
=j)//从区间两端交替向中间扫描,到i=j为止
{
while(j>i&&u[j].count<=temp)//从右向左,找第1个小于temp的u[j]
{j--;}
u[i].count=u[j].count;//u[i]和u[j]交换
u[i].password=u[j].password;
while(i=temp)//从左向右,找第1个大于temp的u[j]
{i++;}
u[j].count=u[i].count;//u[i]和u[j]交换
u[j].password=u[i].password;
}
u[i].count=temp;
u[i].password=temp1;
QuickSort(u,s,i-1);//左区间递归
QuickSort(u,i+1,t);//右区间递归
}
}
voidQuickSortId(Useru[],ints,intt)
{
inti=s,j=t;
inttemp;
stringtemp1;
if(s{
temp=u[s].user_id;//第1个元素作为基准
temp1=u[s].password;
while(i!
=j)//从区间两端交替向中间扫描,到i=j为止
{
while(j>i&&u[j].user_id<=temp)//从右向左,找第1个小于temp的u[j]
{j--;}
u[i].user_id=u[j].user_id;//u[i]和u[j]交换
u[i].password=u[j].password;
while(i=temp)//从左向右,找第1个大于temp的u[j]
{i++;}
u[j].user_id=u[i].user_id;//u[i]和u[j]交换
u[j].password=u[i].password;
}
u[i].user_id=temp;
u[i].password=temp1;
QuickSortId(u,s,i-1);//左区间递归
QuickSortId(u,i+1,t);//右区间递归
}
}
//堆排序,建立堆
voidsift(Userr[],intlow,inthigh)
{
inti=low,j=2*i;//j为i的左子树
inttemp=r[i].count;
stringtemp1;
temp1=r[i].password;
while(j<=high)
{
if(jif(temp{
r[i].count=r[j].count;//将r[j]放到根节点上
r[i].password=r[j].password;
i=j;//修改i和j,以向下筛选
j=2*i;
}
elsebreak;
}
r[i].count=temp;//被筛选节点放入最后位置,即最大或最小值
r[i].password=temp1;
}
voidsiftId(Userr[],intlow,inthigh)
{
inti=low,j=2*i;//j为i的左子树
inttemp=r[i].user_id;
stringtemp1;
temp1=r[i].password;
while(j<=high)
{
if(jif(temp{
r[i].user_id=r[j].user_id;//将r[j]放到根节点上
r[i].password=r[j].password;
i=j;//修改i和j,以向下筛选
j=2*i;
}
elsebreak;
}
r[i].user_id=temp;//被筛选节点放入最后位置,即最大或最小值
r[i].password=temp1;
}
//归并排序
voidMerge(UserR[],intlow,intmid,inthigh,intn)
{
User*R1[IdNum];
inti=low,j=mid+1,k=0;//k是E1的下标,i、j分别为第1、2段的下标
for(inth=0;h<=high;h++)
{
R1[h]=newUser;//动态分配空间
}
while(i<=mid&&j<=high)//在第1段和第2段均未扫描完时循环
if(R[i].count<=R[j].count)//将第2段中的元素放入R1中
{
R1[k]->count=R[j].count;
R1[k]->password=R[j].password;
j++;k++;
}
else//将第1段中的元素放入R1中
{
R1[k]->count=R[i].count;
R1[k]->password=R[i].password;
i++;k++;
}
while(i<=mid)//将第2段余下部分复制到R1中
{
R1[k]->count=R[i].count;
R1[k]->password=R[i].password;
i++;k++;
}
while(j<=high)//将第1段余下部分复制到R1中
{
R1[k]->count=R[j].count;
R1[k]->password=R[j].password;
j++;k++;
}
for(k=0,i=low;i<=high;k++,i++)//将R1复制回R中
{
R[i].count=R1[k]->count;
R[i].password=R1[k]->password;
}
}
voidMergePass(UserR[],intlength,intn)
{
inti;
for(i=0;i+2*length-1{
Merge(R,i,i+length-1,i+2*length-1,n);
}
if(i+length-1}
voidMergeSort(UserR[],intn)
{
intlength;
for(length=1;length{
MergePass(R,length,n);
}
}
voidMergeId(UserR[],intlow,intmid,inthigh,intn)
{
User*R1[IdNum];
inti=low,j=mid+1,k=0;//k是E1的下标,i、j分别为第1、2段的下标
for(inth=0;h<=high;h++)
{
R1[h]=newUser;//动态分配空间
}
while(i<=mid&&j<=high)//在第1段和第2段均未扫描完时循环
if(R[i].user_id<=R[j].user_id)//将第2段中的元素放入R1中
{
R1[k]->user_id=R[j].user_id;
R1[k]->password=R[j].password;
j++;k++;
}
else//将第1段中的元素放入R1中
{
R1[k]->user_id=R[i].user_id;
R1[k]->password=R[i].password;
i++;k++;
}
while(i<=mid)//将第2段余下部分复制到R1中
{
R1[k]->user_id=R[i].user_id;
R1[k]->password=R[i].password;
i++;k++;
}
while(j<=high)//将第1段余下部分复制到R1中
{
R1[k]->user_id=R[j].user_id;
R1[k]->password=R[j].password;
j++;k++;
}
for(k=0,i=low;i<=high;k++,i++)//将R1复制回R中
{
R[i].user_id=R1[k]->user_id;
R[i].password=R1[k]->password;
}
}
voidMergePassId(UserR[],intlength,intn)
{
inti;
for(i=0;i+2*length-1{
MergeId(R,i,i+length-1,i+2*length-1,n);
}
if(i+length-1}
voidMergeSortId(UserR[],intn)
{
intlength;
for(length=1;length{
MergePassId(R,length,n);
}
}
//基数排序
voidRadixSort(RecType1*&p,intr,intd)//p为待排序序列链表指针,r为基数,d为关键字位数
{
RecType1*head[10],*tail[10],*t;//定义各链队的首尾指针
inti,j,k;
for(i=0;i<=d-1;i++)//从低位到高位循环
{
for(j=0;jhead[j]=tail[j]=NULL;
while(p!
=NULL)//分配:
对于原链表中每个结点循环
{
inttemp;
intitemp=i;
temp=atoi(p->data);
if(i==0)
{
if(temp<10)
{
itemp=0;
k=p->data[itemp]-'0';//找第k个链队
}
elseif(temp>9&&temp<100)
{
itemp=1;
k=p->data[itemp]-'0';//找第k个链队
}
elseif(temp>99&&temp<1000)
{
itemp=2;
k=p->data[itemp]-'0';//找第k个链队
}
elseif(temp>999)
{
itemp=3;
k=p->data[itemp]-'0';//找第k个链队
}
}
elseif(i==1)
{
if(temp<10)
{
k=0;
}
elseif(temp>9&&temp<100)
{
itemp=0;
k=p->data[itemp]-'0';//找第k个链队
}
elseif(temp>99&&temp<1000)
{
itemp=1;
k=p->data[itemp]-'0';//找第k个链队
}
elseif(temp>999)
{
itemp=2;
k=p->data[itemp]-'0';//找第k个链队
}
}
elseif(i==2)
{
if(temp<10)
{
k=0;
}
if(temp>9&&temp<100)
{
k=0;
}
elseif(temp>99&&temp<1000)
{
itemp=0;
k=p->data[itemp]-'0';//找第k个链队
}
elseif(temp>999)
{
itemp=1;
k=p->data[itemp]-'0';//找第k个链队
}
}
elseif(i==3)
{
if(temp<10)
{
k=0;
}
if(temp>9&&temp<100)
{
k=0;
}
elseif(temp>99&&temp<1000)
{
k=0;
}
elseif(temp>999)
{
itemp=0;
k=p->data[itemp]-'0';//找第k个链队
}
}