资源描述
计算机程序设计实践报告
餐饮大众点评
1 引言
本课程是基于广受好评的独立第三方消费点评网站——大众点评网中的餐饮点评系统设计的。大众点评网于2003年4月成立于上海。其一直致力于城市消费体验的沟通和聚合。首创并领导的第三方评论模式已成为互联网的一个新热点。大众点评移动客户端通过移动互联网,结合地理位置以及网友的个性化消费需求,为网友随时随地提供餐饮、购物、休闲娱乐及生活服务等领域的商户信息、消费优惠以及发布消费评价的互动平台,这种贴心的设计使其已成为人们本地生活必备的工具。
而其中大众点评网主要致力的餐饮点评服务类尤为大众所喜爱。它做到了使商户中所有的评价信息都来源于大众,服务于大众。每个人都可以自由发表对商户的评论,好则誉之,差则贬之,以此来向大家分享自己的消费心得。它的种种优点使我们对这个评价系统非常感兴趣,所以我们决定选用大众点评网中的餐饮评价模块来作为我们这次课程设计的题目。
2 需求分析
2.1 系统功能分析
1. 对菜品(餐馆名称、菜系、菜名)进行管理
2. 进行评分管理-计算分值、添加评分、添加评价和建议
3. 给各种菜打分,包括评分,写评语,写建议
4. 菜品排名
2.2 系统设计目标
1. 对菜品(餐馆名称、菜系、菜名)进行管理,根据用户选择,输出当前餐厅的菜系菜名
2. 进行评分管理-计算分值、添加评分、添加评价和建议,根据评分的次数和总数计算评分,并根据用户的评分,选择性将评价放入好评,中评或差评中
3. 给各种菜打分,包括评分,写评语,写建议
4. 给餐厅打分,包括对总体评价,口味,服务,环境的星级打分
5. 菜品排名,给所有餐厅根据其总体评价的星级排名,并给餐厅内每道菜按照其评分排名
6. 添加商户,在原有餐厅的基础上,添加新的餐厅菜系菜名,并可以对其进行点评,排名
7. 餐厅查找,根据用户输入的餐厅名称,输出对应餐厅的菜系菜名
3 系统设计
3.1 系统功能设计
1.逛一逛模块 功能:查看各个餐馆的菜系菜品,即菜品管理
1.1店家模块 功能:依次显示所有餐馆名
2.查找模块 功能:根据输入的餐馆名称查找相应的餐馆并输出菜品信息
3.热门餐厅模块 功能:根据总体评价的排名依次显示餐厅星级,即餐厅排名
4.添加商户模块 功能:添加商户,即添加餐馆及其菜系菜名
5..菜系模块 功能:显示所选餐厅菜系
5.1菜名模块 功能:显示所选餐厅菜系的所有菜名
5.1.1写点评模块 功能:给单道菜以及其所在餐厅评分
5.1.2查看评价模块 功能:显示菜的评价
5.1.3查看建议模块 功能:显示菜的建议
5.1.4查看在店中排名模块 功能:显示菜在餐厅中的排名
5.1.5退出模块 功能:退出对单道菜的操作,返回主界面
3.2 系统工作流程
3.3 类设计与类结构(小四号宋体加粗)
class Menu //菜品类
{
public:
Menu();
int Restaurant(); //输出餐馆
int StyOfCooking(int); //输出菜系
void addRestaurant(); //添加商户
string getRestaurant(int); //得到餐馆名称
int getRest(int); //得到餐馆所有菜数目
int getStyoc(int); //得到餐馆所有菜系数目
int getNamoc(int,int); //得到餐馆某一菜系所有菜数目
int geta(); //得到a
string getnam(int,int,int); //得到菜名
int getNumOfNam(int,int,int); //得到菜的编号
int getBeforNam(int); //得到某一餐馆之前所有餐馆共有的菜数目
private:
static int a; //餐馆个数
int b,c; //菜系菜名数目
int restaurant,styoc; //餐馆,菜系编号
static string rest[100]; //餐馆数组
static string sty[100][100]; //菜系数组
static string nam[100][100][100]; //菜名数组
};
class Remark //评分类
{
public:
Remark();
void Choose(int i); //选择操作
void Refectory(); //餐馆点评
int getrr(); //得到rr
int getall(); //得到all
int gettaste(); //得到taste
int getenvironment(); //得到 environment
int getserve(); //得到 serve
void Mark(); //菜点评
void Evaluate(); //显示评价
void Advice(); //显示建议
double getRemark(); //得到 Remark
protected:
int aa,bb,cc,x,rr; //非常好,很好,好,一般,差的评价次数,总评分,餐厅评价次数
double mark; //菜的分数
int all,taste,environment,serve; //总体评价,口味,环境,服务总分数
string goodComment[100],mediumComment[100],badComment[100],advice[100]; //好评数组,中评数组,差评数组
};
class Review //点评类
{
public:
Review();
void Hot(); //热门餐厅
void out(int); //输出星级
int allall(int); //餐厅总体评价分数
int alltaste(int); //餐厅口味分数
int allserve(int); //餐厅服务分数
int allenvironment(int); //餐厅环境分数
void Add(); //添加商户
int NamOfCooking(); //显示菜名
void Find(); //查找
void remark(); //点评
void Ranking(); //排名
private:
int xx,yy,zz; //餐馆,菜系,菜名编号
Menu myMenu; //菜品类对象 myMenu
Remark myRemark[100]; //评分类对象数组 myRemark[100]
};
3.4 开发与运行环境(小四号宋体加粗)
Microsoft Visual C++6.0
4 设计与实现
(1) 界面设计
主界面:
“逛一逛”界面:
“查找”界面:
“热门餐厅”界面:
“添加商户”界面:
单道菜写点评以及对当前菜所在餐厅的评价界面:
单道菜的查看评价与建议界面(点评前):
单道菜的排名界面(点评前):
对单道菜操作的退出界面:
(2) 设计每个模块的算法和流程
【Review类】
private:
int xx,yy,zz; //【注释①】
Menu myMenu; //菜单类的对象
Remark myRemark[100]; //评分类的对象数组,一个对象对应一道菜
public:
【构造函数】
Review():进入界面进行各种操作
1.输出标题,提醒用户已进入大众点评。
2.用“while(1)”做一个无限循环来包含函数中其余的内容,在循环的末尾处询 问用户是否退出(①是 ②否),根据用户的输入“cin>>j;”来判断是否退出循环“if(j==1)break;”以此实现多次评价,查看,添加商户等功能。
3.循环开头处输出主界面的四个选项“1.逛一逛 2.查找 3.热门餐厅 4.添加商 户”。然后执行一个“switch”多分支选择语句。
“case 1”即选择了主界面中的“逛一逛”,执行私有成员中的Menu类的对象myMenu(以后将直接用myMenu,不再做解释说明)中的两个函数和“NamOfCooking()”函数【注释②】,并将返回值分别赋值给私有成员中的xx,yy,zz【注释①】.然后执行“remark()”函数,进行单个菜的评价等功能。
“case 2”即选择了主界面中的“查找”,执行“Find()”函数,对用户输入的餐厅进行查找。
“case 3”即选择了主界面中的“热门餐厅”,执行“Hot()”函数,按餐厅评分排名输出热门餐厅以供用户选。
“case 4”即选择了主界面中的“添加商户”,执行“Add()”函数,进行餐厅的添加。
【成员函数】:
remark():对所选的菜进行评价等功能
1. 用“while(1)”做一个无限循环来包含函数中其余的内容,在循环的末尾处询 问用户是否退出(①后退 ②退出),根据用户的输入“cin>>s;”来判断是否退出循环“if(s==2)break;”以此实现对一道菜多次评价,多种操作的功能
2.在循环内输出“①.写点评 ②.查看评价 ③.查看建议 ④.查看在店中排名 ⑤.退出”以供用户选择
3.将用户的选择存在d中,如果d小于等于3,则执行“myRemark[myMenu.get
NumOfNam(xx,yy,zz)-1].Choose(d)” 【注释③④】,即根据用户所选,调用评分类中的函数进行选项中的操作
4.如果d等于4,则调用Ranking()函数
5.如果d等于5,则break,退出循环
Find():对用户输入的餐厅进行查找
1.让用户输入想要查找的餐厅,将其赋值给refectory
2.执行for循环语句,初始时i=0每循环一次i+1,当输入的餐厅与已有餐厅名字相同时退出循环。即当“myMenu.getRestaurant(i)==refectory”时【注释③】,执行“break”
3.执行if语句,如果上一步中的i小于餐厅的数量“if(i<myMenu.geta())”【注释③】,则将i+1赋值给xx,之后再执行“yy=myMenu.StyOfCooking(xx);zz=NamOfCooking();”,【注释①②】。
4.如果没有满足if的条件,则执行else语句,告诉用户没有他要查找的餐厅。
NamOfCooking():输出所选餐厅菜系的菜名单目,返回值为用户所选的菜名
1.用for循环语句判断当前这家餐厅所有菜系中共有多少道菜,即j的大小
2.用for循环语句循环j次,输出这家餐厅的所有菜名及其评分。循环内执行“p=myMenu.getNumOfNam(xx,yy,i+1)-1;cout<<myMenu.getnam(xx-1,yy-1,i)<<""<<myRemark[p].getRemrk()<<"分"”【注释③④】
Hot():按餐厅的评分排名输出热门餐厅以供用户选择
1.执行for循环语句,将所有餐厅的评分依次放在rank数组里“rank[i]=allall(i)”(allall(x):根据参数x的值返回餐厅评分)
2.运用for循环套嵌,把上述rank数组中的评分数从大到小进行排序
3.再运用for循环套嵌,实现按照评分的排序将餐厅排序,再把排名放在c数组里。实现方法:在循环中加入if语句,如判断排序后的rank数组中的第一个数值与第二家餐厅的评分数值相等,就将数字2放在c数组的第一个成员中。另外,在执行的过程中会存在多家餐厅评分相同的情况,故在执行的if语句中加入一个for循环,判断当前这家餐厅的序号是否已经放入过c数组中,如果已存在过,则不执行上述过程,继续进行循环。如果没存在过,则执行,并跳出单层循环。
4.运用单层for循环,根据c数组中的餐厅编号的排名,用“out(x)”函数,依次输出餐厅的星级评分,并将所选的餐厅序号赋值给xx,再执行“yy=myMenu.StyOfCooking(xx)
zz=NamOfCooking()”,【注释①②】。
allall(x):返回编号为x的餐厅的“总体评价”的分数
1.运用for循环,得到餐厅“总体评价”的总评分和总评价次数【注释④】
2.运用if语句,判断总评价次数是否为零,若为零,则返回0,即餐厅“总体评价”评分为零。若不为零,则返回总评分除以总评价次数以后的值。
alltaste(x):返回编号为x的餐厅的“口味”的分数
1.运用for循环,得到餐厅“口味”的总评分和总评价次数【注释④】
2.运用if语句,判断评分次数是否为零,若为零,则返回0,即餐厅“口味”评分为零。若不为零,则返回总评分除以总评价次数以后的值。
allenvironment(x):返回编号为x的餐厅的“环境”的分数
1.运用for循环,得到餐厅“环境”的总评分和总评价次数【注释④】
2.运用if语句,判断评分次数是否为零,若为零,则返回0,即餐厅“环境”评分为零。若不为零,则返回总评分除以总评价次数以后的值。
allserve(x):返回编号为x的餐厅的“服务”的分数
1.运用for循环,得到餐厅“服务”的总评分和总评价次数【注释④】
2.运用if语句,判断评分次数是否为零,若为零,则返回0,即餐厅“服务”评分为零。若不为零,则返回总评分除以总评价次数以后的值。
out(x):输出参数x个★,5-x个☆
1. 运用两个for循环,输出x个★,5-x个☆。
Add():添加商户
1. 用“while(1)”做一个无限循环来包含函数中其余的内容,在循环的末尾处询问用户是否继续添加商户(①继续添加商户 ②否),根据用户的输入“cin>>i;”来判断是否退出循环“if(i==2)break;”
2. 循环内执行myMenu.addRestaurant()函数【注释③】
Ranking():菜排名
1.将c数组用for循环语句赋初值后(为了在之后的操作中判定c数组中的元素是否已赋值),执行for循环语句,将当前根据xx的值得到的餐厅的所有菜的评分依次放在a数组里“a[i]=myRemark[z-1+i].getRemark()”【注释④】
2.运用for循环套嵌,把上述a数组中的评分数从大到小进行排序
3.再运用for循环套嵌,实现c数组中第x个元素的值等于当前餐厅内第x道菜的排名。算法及思路同Hot()函数中第4步类似
4.输出当前菜的排名
【注释】:1.xx:用户所选餐厅编号
yy:用户所选菜系编号
zz:用户所选菜名编号
2.myMenu.Restaurant():输出餐厅单目,返回值为用户所选的餐厅编号
myMenu.StyOfCooking(x):输出所选餐厅菜系单目,返回值为用户所选的菜系
NamOfCooking():输出所选餐厅菜系的菜名单目,返回值为用户所选的菜名
3.myMenu.getRestaurant(x):根据参数x,返回对应编号的餐厅名
myMenu.geta():得到myMenu对象中所有餐厅的总数量
myMenu.getBeforNam(x):返回编号为x的餐厅之前所有菜名的数目
myMenu.getRest(x):返回编号为x的餐厅拥有菜名的数目
myMenu.addRestaurant():添加商户
myMenu.getnam(x,y,z):返回编号为x的餐厅中编号为y的菜系中编号为z的菜的名称
myMenu.getNumOfNam(x,y,z):返回值为编号为x的餐厅中编号为y的菜系中编号为z的菜在所有菜中的序号,即在Remark类中拥有100个成员的myRemark对象数组中的成元序号
4.myRemark[i].getall():返回在评价当前菜时评价所在餐厅的“总体评价”的分数
myRemark[i].getrr():返回在评价当前菜时评价所在餐厅的次数
myRemark[i].Choose(x):根据用户的选择进行写点评、查看评价等操作
(3) 测试与运行结果
测试菜品管理功能(逛一逛):
测试查找功能(查找):
查找到:
未查找到:
测试添加商户功能(添加商户):
添加“甜甜屋”商户后:
测试对单道菜的操作功能(写点评、查看评价、查看建议、查看排名):
写点评:
添加评价后查看评价,查看建议:
添加评价后,查看在店中排名:
测试对单道菜操作的退出功能(退出):
选择,否:
选择,是:
测试对餐厅进行评分:
对餐厅评价:
评价后餐厅的星级与排名
5 结语
5.1结论与讨论
为了完成这次大众点评餐饮类点评系统的设计,我们查阅了很多资料,并参考了大众点评网的界面,从最开始的只有点评功能增加到可以添加商户、餐厅评分,将评价归类等许多功能,这个过程让我们受益良多,也渐渐发现了程序实现功能时的趣味性,让我们拥有了想要实现更多功能的想法,比如对单道菜和餐厅同时赋予分数和星级的形式。最开始将所有类联系在一起我们采取的是继承的方式,之后经过讨论发现这种做法并不能很好的实现联系,所以我们采取了做成私有成员的形式,基本实现了这次课设的目标。
5.2 设计体会
通过课程设计的训练,我进一步学习和掌握了对程序的设计和编写,加强了对类的认识,从中体会到了面向对象程序设计的方便和巧妙。懂得了在进行编写一个程序之前,要有明确的目标和整体的设计思想。另外某些具体的细节内容也是相当的重要。这些宝贵的编程思想和从中摸索到的经验都是在编程的过程中获得的宝贵财富。这些经验对我以后的编程会有很大的帮助的,我要好好利用。
参考文献
[1] 刘佳敏,马广焜,常燕等.C++面向对象程序设计双语教程(第2版).北京:国防工业出版社
[2] 钱能.C++程序设计教程(修订版).北京:清华大学出版社
[3] 编程论坛:
[4] 大众点评:
《计算机程序设计实践》课程设计任务划分
课程设计题目:
姓 名
设计职务
任 务
工作量比例
马一尤
组长
点评类
40%
曲思洁
组员
评分类
30%
常浩
组员
菜品类
30%
附录
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//- - 餐饮大众点评.prj - -
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Menu.h //菜品类
Remark.h //评价类
Review.cpp //点评类和测试函数
//* * * * * * * * * * * * * * * * * * * * * * * * *
//* * Menu.h * *
//* * * * * * * * * * * ** * * * * * ** * * * * * *
# include <iostream>
# include <string>
using namespace std;
class Menu //菜品类
{
public:
Menu(){}
int Restaurant() //输出餐馆
{
cout<<"\n ☆☆☆☆ 店家 ☆☆☆☆\n\n ";
for(int i=0;i<a;i++)
{
cout<<"§"<<i+1<<". "<<rest[i]<<" ";
}
cout<<endl;
cin>>restaurant;
return restaurant;
}
int StyOfCooking(int x) //输出菜系
{
cout<<"\n ☆☆☆☆ 菜系 ☆☆☆☆\n\n ";
for(int j=0;j<100;j++)
{
if(sty[x-1][j]=="") break;
}
for(int i=0;i<j;i++)
{
cout<<"§"<<i+1<<". "<<sty[x-1][i]<<" ";
}
cout<<endl;
cin>>styoc;
return styoc;
}
void addRestaurant() //添加商户
{
a++;
cout<<"★ 商户名称:";
cin>>rest[a-1];
cout<<"\n菜系数目(填数字哦⊙_⊙):";
cin>>b;
for(int i=0;i<b;i++)
{
cout<<"\n★菜系"<<i+1<<":";
cin>>sty[a-1][i];
cout<<"\n菜名数目(填数字哦⊙_⊙):";
cin>>c;
for(int j=0;j<c;j++)
{
cout<<"\n★菜名"<<j+1<<":";
cin>>nam[a-1][i][j];
}
}
cout<<"\n★商户:"<<rest[a-1]<<" 添加完毕"<<endl;
}
string getRestaurant(int x) //得到餐馆名称
{
return rest[x];
}
int getRest(int x) //得到餐馆所有菜数目
{
int all=0;
for(int i=0;i<100;i++)
{
if(sty[x-1][i]=="")
break;
for(int j=0;j<100;j++)
{
if(nam[x-1][i][j]=="")
break;
}
all+=j;
}
return all;
}
int getStyoc(int x) //得到餐馆所有菜系数目
{
for(int i=0;i<100;i++)
{
if(sty[x-1][i]=="") break;
}
return i;
}
int getNamoc(int x,int y) //得到餐馆某一菜系所有菜数目
{
for(int i=0;i<100;i++)
{
if(nam[x-1][y-1][i]=="") break;
}
return i;
}
int geta() //得到a
{
return a;
}
string getnam(int x,int y,int z) //得到菜名
{
return nam[x][y][z];
}
int getNumOfNam(int x,int y,int z) //得到菜的编号
{
int rank=0;
for(int i=1;i<x;i++)
{
rank+=getRest(i);
}
for(int j=1;j<y;j++)
{
rank+=getNamoc(x,j);
}
rank+=z;
return rank;
}
int getBeforNam(int x) //得到某一餐馆之前所有餐馆共有的菜数目
{
int all=0;
for(int i=0;i<x;i++)
{
all+=getRest(i+1);
}
return all;
}
private:
static int a; //餐馆个数
int b,c; //菜系菜名数目
int restaurant,styoc; //餐馆,菜系编号
static string rest[100]; //餐馆数组
static string sty[100][100]; //菜系数组
static string nam[100][100][100]; //菜名数组
};
string Menu::rest[100]={"蟹堡王","糖糖小家","福记"};
string Menu::sty[100][100]={{"鲁菜","川菜","湘菜","饮品"},{"东北菜","粤菜","饮品"},{"闽菜","苏菜"}};
string Menu::nam[100][100][100]={{{"一品豆腐","香酥鸡"},{"鱼香肉丝","回锅肉"},{"腊味合蒸"},{"橙汁","雪碧"}},{{"小鸡炖蘑菇","锅包肉","猪肉炖粉条"},{"梅菜扣肉","白斩鸡"},{"辣白菜汤","牛肉萝卜汤"}},{{"青椒炒肉丝","三杯鸡"},{"贵妃鸡翅","金玉满堂"}}};
int Menu::a=3;
//* * * * * * * * * * * * * * * * * * * * * * * * *
//* * Remark.h * *
//* * * * * * * * * * * ** * * * * * ** * * * * * *
# include <iostream>
# include <iomanip>
# include <string>
class Remark //评分类
{
public:
Remark()
{
all=0;
taste=0;
environment=0;
serve=0;
mark=0;
aa=0;
bb=0;
cc=0;
rr=0;
x=0;
}
void Choose(int i) //选择操作
{
switch(i)
{
case 1:Mark();break;
case 2:Evaluate();break;
case 3:Advice();break;
}
}
void Refectory() //餐馆点评
{
int a,b,c,d;
cout<<"\n ☆☆☆☆ 店铺评价 ☆☆☆☆\n\n";
cout<<" ⊙_⊙亲,5星好评,您打算给我们几颗星呢?\n";
cout<<"\n★总体评价:";
cin>>a;all+=a;
cout<<"★口味:";
cin>>b;taste+=b;
cout<<"★环境:";
cin>>c;environment+=c;
cout<<"★服务:";
cin>>d;serve+=d;
rr++;
}
int getrr() //得到rr
{
return rr;
}
int getall() //得到all
{
return all;
}
int gettaste() //得到taste
{
return taste;
}
int getenvironment() //得到 environment
{
return environment;
}
int getserve() //得到 serve
{
return serve;
}
void Mark() //菜点评
{
int b,s;
if(x!=0) mark=(double)x/(double)(aa+bb+cc);
cout<<" ★这道菜的评分 : "<<setiosflags(ios::fixed)<<setprecision(1)<<mark<<"分\n"<<endl;
cout<<"1.非常好: 10分 2.很好: 8分 3.好: 6分 4.一般: 4分 5.很差: 2分"<<endl;
cin>>b;
switch(b)
{
case 1:x+=10;aa++;mark=x/(aa+bb+cc);break;
case 2:x+=8;aa++;mark=x/(aa+bb+cc);break;
case 3:x+=6;aa++;mark=x/(aa+bb+cc);break;
case 4:x+=4;bb++;mark=x/(aa+bb+cc);break;
case 5:x+=2;cc++;mark=x/(aa+bb+cc);break;
}
cout<<"\n ⊙_⊙亲,您对这道菜的评价如何,口味满意吗?\n\n★评价:";
switch(b)
{
case 1:
case 2:
case 3:cin>>goodComment[aa-1];break;
case 4:cin>>mediumComment[bb-1];break;
case 5:cin>>badComment[cc-1];break;
}
cout<<"\n ⊙_⊙亲,请给我们一些建议,更好的为您服务吧!\n\n★建议:";
cin>>advice[aa+bb+cc-1];
cout<<endl;
cout<<" ★进行餐厅评分\n\n ① 是 ② 否\n";
cin>>s;
if(s==1) Refectory();
}
void Evaluate() //显示评价
{
cout<<" ☆好评("<<aa<<"条):\n"<<endl;
for(int h=0;h<aa;h++)
cout<<" "<<h+1<<"."<<goodComment[h]<<endl;
cout<<"\n ☆中评("<<bb<<"条):\n"<<endl;
for(int j=0;j<bb;j++)
cout<<" "<<j+1<<"."<<mediumComment[j]<<endl;
cout<<"\n ☆差评("<<cc<<"条):\n"<<endl;
for(int k=0;k<cc;k++)
cout<<" "<<k+1<<"."<<badComment[k]<<endl;
cout<<endl;
}
void Advice() //显示建议
{
cout<<" ☆建议("<<aa+bb+cc<<"条):\n"<<endl;
for(int i=0;i<(aa+bb+cc);i++)
{
cout<<" "<<i+1<<"."<<advice[i]<<endl;
}
cout<<endl;
}
double getRemark() //得到 Remark
{
return mark;
}
protected:
int aa,bb,cc,x,rr; //非常好,很好,好,一般,差的评价次数,总评分,餐厅评价次数
double mark; //菜的分数
int all,taste,environment,serve; //总体评价,口味,环境,服务总分数
string goodComment[100],mediumComment[100],badComment[100],advice[100]; //好评数组,中评数组,差评数组
};
//* * * * * * * * * * * * * * * * * * * * * * *
展开阅读全文