SSD5 数据结构 Course Design Exercise 4 解析

来源:互联网 发布:软件测试流程是什么 编辑:程序博客网 时间:2024/05/23 22:39

在上一个assignment中我们完成了Viewing Advertisements by Categories的遍历功能,包括Category和Categories两个具体类的实现。

Exercise 4 非常有意思,闲言少叙,我们直接上实验说明:

Sorting and Keyword Filtering

This assessment extends the Auction project to sort and filter by keyword the advertised items. A user of the system will have the ability to sort by the seller email address, the posting date, the closing date, and the quantity of items.

To complete this exercise, add sorting and filtering support to class Listing.

Changes to class Listing

Changes to class Listing will allow a user of class Listing to sort advertisements and filter advertisements based on a keyword. To support these new requirements, class Listing has been modified to add methods sort and filter.

·  virtual Listing sort(string field); 

This is a new method. This method returns a copy of the invoking Listing object sorted by the field name given in the parameter. Use an appropriate STL sorting function to sort the advertisements. To sort based on the field name given by the parameter field, consider using an STL sort function that uses a predicate to determine object equality. The field names that can be passed into this function are "email," "start," "close," and "quantity."

·  virtual Listing filter(string keyword); 

This is a new method. This method is a new instance of a Listing object that contains only those advertisements whose name or description contains the string given by the parameter keyword. If the parameter keyword equals the empty string (""), return a copy of the invoking Listing object. Use STL functions where appropriate. Some STL functions to consider are copy, remove_if, for_each, and find. The member function find of class string should be considered as well. Regardless of the STL functions used, a solution should not use any for-loops or while-loops.

没有任何其他新的类的需求,只是在Listing类上完成两个操作即可,一个是关键字排序,一个是关键字筛选。而且不能用for循环和while循环。一般这种时候STL的伟大就体现出来了。都说C++很庞大,在它庞大的同时也提供了很多便于编程人员进行操作的库,STL就是一个非常强大的算法和容器的库。


在实现sort()方法的时候我们需要用到std::sort的函数来辅助实现,std::sort()的函数原型如下:

template<class AccessIterator, class Functor>

sort(AccessIterator begin, AccessIterator end, Functor func);

template<class AccessIterator, class Functor>

sort(AccessIterator begin, AccessIterator end);

begin 和 end 是遍历当前容器的指针,func是一个仿函数,提供比较的方法。(sort方法的实现据了解是quick sort,具体方法没做太多了解,这里不加过多的叙述)

事实上有两种实现方案,可以把func写为顶层函数,不属于任何类,或者是把func写为static数据成员进行操作,二者可以达到相同的效果,代码都可以正常运行。从优化的角度上考虑,使用仿函数的手法,把判定条件封装到一个KeySort类中进行实现,通过调用含参构造方法,可以达到更高一个层次的封装。

下面是静态数据成员实现的KeySort类:

class KeySort{friend class Listing;static bool comp_email(Advertisement* obj_a, Advertisement* obj_b){return obj_a->getEmail() < obj_b->getEmail();}static bool comp_quantity(Advertisement* obj_a, Advertisement* obj_b){return obj_a->getQuantity() < obj_b->getQuantity();}static bool comp_start(Advertisement* obj_a, Advertisement* obj_b){return obj_a->getStart() < obj_b->getStart();}static bool comp_close(Advertisement* obj_a, Advertisement* obj_b){return obj_a->getClose() < obj_b->getClose();}public:KeySort() {  }Listing KeySortFunc(Listing copyObject, string field){if (field == "email"){std::sort(copyObject.begin(), copyObject.end(), comp_email);}if (field == "quantity"){std::sort(copyObject.begin(), copyObject.end(), comp_quantity);}if (field == "start"){std::sort(copyObject.begin(), copyObject.end(), comp_start);}if (field == "close"){std::sort(copyObject.begin(), copyObject.end(), comp_close);}return copyObject;}Listing keyFilter(Listing Object, string keyword){KeyFilter obj(keyword, Object);for_each(Object.begin(), Object.end(), obj);return obj.getObjectRes();}~KeySort() { }};

在Listing类内,直接调用KeySort对象下的KeySortFunc即可实现排序

Listing Listing::sort(string field){KeySort sortObj;return sortObj.KeySortFunc(*this, field);}

最后附上使用仿函数来完成的filter功能

Listing Listing::filter(string keyword){Listing copyObject(*this), result;if (keyword == "")             //边界条件,如果输入字符串空,返回当前广告列表{return copyObject;}KeyFilter obj_x;obj_x = for_each(this->begin(), this->end(), KeyFilter(keyword,result));return obj_x.getObjectRes();}
KeyFilter类的实现:

#pragma once#include"Listing.h"class KeyFilter{public:KeyFilter(){}KeyFilter(string key, Listing &objectRes);~KeyFilter();void operator()(Advertisement *ad){if (ad->getTitle().find(key) != string::npos || ad->getBody().find(key) != string::npos){objectRes.add(ad);}}Listing getObjectRes(){return this->objectRes;}private:string key;Listing objectRes;};KeyFilter::KeyFilter(string key, Listing &objectRes){this->key = key;this->objectRes = objectRes;}KeyFilter::~KeyFilter(){}
重载函数调用运算符operator (),直接调用构造函数。关于仿函数的讲解在编者之前的文章中有介绍,如果有不清楚的地方可以直接查看。