SSD5 数据结构 Course Design Exercise 3 解析

来源:互联网 发布:充值系统源码 编辑:程序博客网 时间:2024/06/05 20:26

SSD5是Carnage Melon非常经典的数据结构课程,iCarnege auction (拍卖系统) 的是SSD5中的一个很经典的课程设计,这段时间我们在做这个题目,所以在这里做一些相关的记录。这里没有对各个类之间的调用关系以及相关的用途进行详细的讲解,只是对部分关键函数的实现进行了一些记录,很多细节没有过多描述,更多的内容需要大家在做的过程中进行探索,这里给出的只是部分实现以及代码片段(能正常运行)。

Exercise 1 和Exercise 2 比较简单,主要是实现了Advertisement、Listing等类中的一些基本操作。这里就直接略过不再赘述,直接从Exercise 3 开始。

Exercise 3 问题原型如下:

This assessment extends the Auction project to allow items to be grouped and displayed in categories. Registered users of the system will have the ability to choose a category when posting an advertisement. Regular users of the system can filter the list of advertisements based on category. Two filters exist. The first filter displays only those items that appear in a selected category. The second filter displays those items that appear in a selected category and all of its sub-categories.

To complete this exercise, you will complete the implementation of class Category and class Categories.

Class Category

Class Category models a category. This class contains private data members for the category name, identification number, and parent identification number. A vector<int> stores the unique identification numbers of the advertisements that belong to this category. A vector<Category*> stores pointers to the sub-categories of each category.

· virtual void findOfferings (Listing::iterator start, Listing::iterator finish, Listing &matches); 

Fills the Listing matches with the advertisements that exist in the invoking category.

·  void findOfferingsRecursive (Listing::iterator start, Listing::iterator finish, Listing &matches); 

This routine fills the Listing matches with the advertisements that exist in the invoking category and all of its sub-categories. This must be implemented as a recursive function.


Class Categories

Class Categories models a collection of categories. This class contains a private data member of type vector<Category*>. This stores information regarding each category that appears in the collection of categories.


实验要求实现Category 和 Categories 两个类中的所有给定方法,两个类主要的功能就是实现按照不同的目录类别来添加拍卖广告,并实现当前目录下的遍历和包含子目录递归遍历的功能其中的核心方法就是void findOfferings()以及void findOfferingsRecursive().下面我们来看一下Category.h的内容

#ifndef CATEGORY_H#define CATEGORY_H#include <string>#include <vector>#include "Listing.h"using namespace std;class Category;istream &operator>>(istream &stream, Category &c);class Category {private:int number;int parent;string name;vector<Category*> sub_categories;vector<int> items;public:Category(void);Category(int parent, string name);virtual int getNumber(void) const;virtual int getParent(void) const;virtual string getName(void) const;virtual void setNumber(int);virtual void setParent(int);virtual void setName(string);virtual void addSubCategory(Category*);virtual void addItem(int);    virtual void findOfferings (Listing::iterator start, Listing::iterator finish, Listing &matches);    virtual void findOfferingsRecursive (Listing::iterator start, Listing::iterator finish, Listing &matches);virtual vector<int>::iterator itemsBegin();virtual vector<int>::iterator itemsEnd();virtual vector<Category*>::iterator subCategoriesBegin();virtual vector<Category*>::iterator subCategoriesEnd();virtual bool operator==(const Category& rhs);};#endif
vector<Category*> sub_Category变量存放的是当前对象内的子目录,vector<int> items中存放的是当前目录下的广告编号。

根据findOfferings的函数签名,我们知道,前台传入的会是某个listing的start和finish指针分别指向容器的头和尾,如果listing对象中的广告和当前目录下的广告序号一致,则把匹配上的广告add到matches对象当中,最后函数的返回值就是完成匹配的matches对象。

processrequest.cpp中,当前类遍历的对应模块如下(以此来推断函数所面向的需求)

else if (req == "TOP_ONLY") {    int category;iss.getline(request, 80);category = atoi(request);Listing filteredByCategory;Category* c = categories[category];c->findOfferings (advertisements.begin(), advertisements.end(),                       filteredByCategory );displayListing(connfd, port, filteredByCategory.begin(), filteredByCategory.end());  }

下面是findOfferings()的具体实现

void Category::findOfferings(Listing::iterator start, Listing::iterator finish, Listing & matches){Listing::iterator it;vector<int>::iterator pit;int len = 0;for (it = start; it != finish; it++){if (len == items.size()){return;}for (pit = items.begin(); pit != items.end(); pit++){if ((*it)->getNumber() == (*pit)){matches.add(*it);len++;}}}}

算法时间复杂度为O(n*m),n为listing被遍历部分的表长,m为items的长度。

那么递归遍历的思路与之类似,这里的递归和树的前序遍历非常类似,主目录可以看做根节点,子目录就是分支节点。

下面附上的是findOfferingsRecursive()的具体实现

void Category::findOfferingsRecursive(Listing::iterator start, Listing::iterator finish, Listing & matches){this->findOfferings(start, finish, matches);vector<Category*>::iterator cit;for (cit = sub_categories.begin(); cit != sub_categories.end(); cit++){(*cit)->findOfferingsRecursive(start, finish, matches);}}
每次递归到下一层目录的时候都可以把当前目录看做子目录进行访问,直接调用findOfferings方法即可,时间复杂度同上。

原创粉丝点击