数据结构课程设计网上拍卖系统实验报告C++文档格式.docx
- 文档编号:19150593
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:19
- 大小:156.32KB
数据结构课程设计网上拍卖系统实验报告C++文档格式.docx
《数据结构课程设计网上拍卖系统实验报告C++文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计网上拍卖系统实验报告C++文档格式.docx(19页珍藏版)》请在冰豆网上搜索。
voidaddOffering(intitem);
boolverifyPasswd(stringpasswd);
一个client除了一些基本的客户信息外,还分别拥有该客户发布的所有广告offerings及所有的竞标bids。
这里的get,set方法都省去不写。
addBid()方法是将Client所竞标的广告的id添加到Client的bids集合里。
addOffering()方法是将Client所发布的广告的id添加到Client的offerins集合里。
verifyPasswd()方法用来Client登录时验证密码的。
Advertisement
intnumber;
//广告的唯一标示符即id
intquantity;
//提供的竞标的数量
stringtitle;
stringseller_email;
stringbody;
Datestart;
Dateclose;
priority_queue<
Bid>
&
getBids(void);
getTopDutchBids(void)const;
Adervitisement的属性除了一些基本的信息外,还拥有截至目前为止该广告的所有竞标情况
即:
getBids()方法可以获得截至目前为止的该广告的所有竞标bids
getTopDutchBids()方法返回值是vector<
该vector里存放的是所有成功的bids,但bid里并非所有的quantity都竞标上了。
Date
intmonth;
intday;
intyear;
inthour;
intminute;
intsecond;
booloperator==(constDate&
rhs);
booloperator<
(constDate&
left);
istream&
operator>
>
(istream&
in,Date&
date)
Date类中重载了操作符==和<
为了判断时间的大小
Group
map<
int,Client*>
objects;
Client*operator[](conststring&
email);
voidadd(Client*ptr);
iteratorbegin();
iteratorend();
Group是Client的集合,使用map实现
在这里重载了[],通过email可以直接获得相应的Client句柄,其他三个方法都是对这个集合的基本操作,添加遍历等
Listing
Advertisement*>
objects
Advertisement*operator[](constint&
number);
voidadd(Advertisement*ptr);
Listingsort(stringfield);
Listingfilter(stringkeyword);
Listing类的属性值只有一个,就是Advertisement的集合。
方法有:
通过重载操作符[],可以通过Advertisement的唯一标识符number获得相应的Advertisement对象句柄,这里是Advertisement*类型的指针
对该集合的一些操作方法,添加和遍历
Sort()方法是按不同的关键字进行排序,方便客户对数据进行分析和决策
Filter()方法是搜索含有Keyword的广告,方便客户从大量的广告中筛选客户需要的
Category
intparent;
stringname;
map<
int,int>
sub_categories;
items;
Category(intparent,stringname);
:
iteratoritemsBegin();
iteratoritemsEnd();
iteratorsubCategoriesBegin();
iteratorsubCategoriesEnd();
voidaddSubCategory(int);
voidaddItem(int);
booloperator==(constCategory&
rhs);
Category的相关属性有本身的id和客户父亲的id,客户的name,sub_categories是该分类下的所有子分类,items是该分类下所有的广告
Category的构造方法;
Items集合和sub_categories集合的遍历,添加;
重载操作符==;
Categories
int,Category*>
objects;
staticconstintTOP_LEVEL;
staticconstintNO_PARENT;
Category*operator[](constint&
voidadd(Category*ptr);
findOfferings(intcategory,Listing:
iteratorstart,
Listing:
iteratorfinish,Listing&
matches);
voidfindOfferingsRecursive(intcategory,Listing:
iteratorstart,
Categories的属性有category的集合对象objects;
以及两个静态常量TOP_LEVEL和NO_PARENT,用来初始化最开始的category的number和parent属性值
Categories的方法有
[]的重载,通过category相应的属性值number可以获得相应的category*;
Add方法,向objects中添加category;
findOfferings(),查找当前分类下的所有广告;
findOfferingsRecursive(),采用递归的方法查找当前分类下的所有广告及当前分类下的所有子分类的所有广告;
Bid
floatamount;
Datedate;
(constBid&
rhs)const;
booloperator==(constBid&
Bid的基本属性及操作符<
==的重载
2、程序设计
介绍顺序按照上面类的先后顺序:
Advertisement中的getTopDutchBids()方法:
思路和代码:
Advertisement:
getTopDutchBids(void)const{
winBids;
//里面存放竞标成功的bid
inttotalWinQuantity=0;
//记录所有成功bid的属性值quantity之和
copyOfBids(this->
bids);
//复制一份Advertisement的bids,否则会丢失竞标失败的相关信息,避免对原数据的直接修改
while(totalWinQuantity<
this->
getQuantity()&
copyOfBids.size()!
=0){
//这里总共有两个限制条件,缺一不可:
//1.totalWinQuantity>
=Advertisement所提供的quantity时退出循环
//2.要对优先权队列进行操作,必须保证其不为空,否则会抛异常
totalWinQuantity+=copyOfBids.top().getQuantity();
//累加bid的quantity
winBids.push_back(copyOfBids.top());
//将amount最大的bid添加到优先权队列winBids中
copyOfBids.pop();
//弹出amount最大的bid,取amount次大的bid
}
returnwinBids;
复杂度分析:
时间复杂度分析:
最好的情况while循环一次,最坏的情况N(其中N为this->
getQuantity()和copyOfBids.size()其中较小的一个)
空间复杂度分析:
需在栈区申请vector<
int,priority_queue<
类型的变量各一个
Bidhistory中displayBidHistory方法的实现:
思路:
displayBidHistory分别传了两个参数,一个是引用型的输出流,一个是Advertisement*,首先要显示的是该广告的一些基本信息,发布者的名字可以通过广告中的email获得,接下来显示竞标情况:
如果没有相应的竞标,则返回,给出相应的提示“该条广告目前没有任何竞标”
如果有竞标,
假如广告提供的quantity=1,则显示该bid的amount和email
假如广告提供的quantity>
1,遍历存放所有成功bid的集合winBids,
假如没有遍历到最后一个bid
遍历中需要将总共成功的quantity累加到winQuantity中,每遍历一次显示该bid的quantity,成功的quantity和失败的quantity,此时总的quantity是客户需要的quantity,失败的quantity等于0
如果客户需要的大于提供的quantity,则成功的quantity为广告提供的quantity
否则成功的quantity等于客户需要的quantity
若遍历到最后一个bid,
令left=advertisement->
getQuantity()-winQuantity
如果bid.getQuantity()<
left,
则成功的quantity等于客户需要的quantity,失败的quantity=0
否则成功的quantity=left
失败的quantity=客户需要的quantity-left
代码实现:
voiddisplayBidHistory(ostringstream&
oss,Advertisement*ad){
Client*c=users[ad->
getEmail()];
oss<
<
"
seller:
"
c->
getFname()<
"
getLname()<
br>
;
start:
ad->
getStart()<
close:
getClose()<
quantity:
getQuantity()<
thenumberofbids:
getBids().size()<
copyOfBids(ad->
getBids());
winBids=ad->
getTopDutchBids();
intwinQuantity=0;
inttheWinQuantityOfLastBid=0;
if(winBids.empty()){
oss<
theaddon'
thaveanybiduntilnow!
return;
if(ad->
getQuantity()==1){
thewinningbidis:
vector<
iteratorit=winBids.begin();
amount:
(*it).getAmount()<
email:
(*it).getEmail()<
winQuantity=(*it).getQuantity();
}else{
oss<
thewinningbidsare:
for(vector<
it!
=winBids.end();
it++){
totalquantity:
(*it).getQuantity()<
cout<
(*it).getQuantity()"
endl;
if(it!
=winBids.end()-1){
oss<
winquantity:
winQuantity+=(*it).getQuantity();
losequantity:
0"
}else{//最后一个bid的处理情况
inttemp=ad->
getQuantity()-winQuantity;
if((*it).getQuantity()<
=temp){//
oss<
winQuantity+=(*it).getQuantity();
}else{
oss<
temp<
winQuantity+=temp;
(*it).getQuantity()-temp<
}
}
}
}
theamountofitemsintheadthathavenotbeenbidonis:
quantity."
,仔细阅读之后知道了这个方法体的大概构架,sort函数第三个参数是个判断条件,为了避免写多个判断条件,可以使用函数对象SortBy来简化程序。
ListingListing:
sort(stringfield){
ListingsortedList;
//acopyoftheinvokingListing
sortedList.objects=this->
SortBysortBy(field);
std:
sort(sortedList.objects.begin(),sortedList.objects.end(),sortBy);
returnsortedList;
}
函数对象(也称“算符”)是重载了“()”操作符的普通类对象。
从语法上讲,函数对象与普通的函数行为类似,实现时需要注意几点:
1,里面所有的属性方法是public.
2,因为要使用外界的参数field,该函数对象得写构造函数
3,对操作符()的重载
函数对象SortBy的实现:
classSortBy{
public:
//thedefaultvalueisprivate!
!
stringfield;
SortBy(stringfield):
field(field){}
booloperator()(Advertisement*ad1,Advertisement*ad2){
if(pare("
email"
)==0){
if(ad1->
getEmail().compare(ad2->
getEmail())<
0)
returntrue;
elsereturnfalse;
……为减少篇幅,雷同代码已省去……
}elseif(pare("
highest"
if(!
ad1->
getBids().empty()&
ad2->
(ad1->
getBids().top()<
getBids().top()))
elsereturnfalse;
lowest"
//在成功的bids里选取amount最小的
getTopDutchBids().empty()&
getTopDutchBids().back()<
getTopDutchBids().back()))
returntrue;
};
下面是lowest的第二种实现方法:
在一个广告的所有bids里选取amount最小的,先拷贝一份priority_queue<
copyOfBids然后pop()直到最后一个,即可获得最小的amount.
/*floatlow1=-1.0,low2=-1.0;
copyOfBids1(ad1->
getBids()),copyOfBids2(ad2->
if(!
copyOfBids1.empty())low1=copyOfBids1.top().getAmount();
while(!
copyOfBids1.empty()){
if(low1>
copyOfBids1.top().getAmount()){
low1=copyOfBids1.top().getAmount();
copyOfBids1.pop();
copyOfBids2.empty())low2=copyOfBids2.top().getAmount();
copyOfBids2.empty()){
if(low2>
copyOfBids2.top().getAmount()){
low2=copyOfBids2.top().getAmount();
copyOfBids2.pop();
if((low1<
low2)&
(low1>
0)&
(low2>
0))returntrue;
*/
需要说明的是SortBy中lowest的排序,就是这个lowest究竟怎么理解,对于一个广告,它有很多bid,设winBids是成功的bid,它存放在向量vector<
里面,totalBids是该广告所有的bid,它存放在priority_queue<
里,那么这个lowest是winBids里的lowest还是totalBids里的lowest,这里我选择前者理由有二:
1.后者的空间复杂度和时间复杂度都比前者高。
因为后者是使用priority_queue<
进行存储的,要取得最小amount,必须一直pop()直到最后一个元素,这提高了时间复杂度,再者不能因为比较大小就对原数据进行修改,所以必须copy一份原先的bids,这又提高了空间复杂度,所以从程序的运行效率来看应该选前者。
2.前者更具有
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 网上 拍卖 系统 实验 报告 C+