某网站,用户可按爱好关注其它用户。
相同爱好的关注可以传递:即如果A以电影直接或间接关注C,而C以电影直接或间接关注F,则认为A也以电影间接关注F
我们把{A,A以电影直接或间接关注的所有用户,以电影直接或间接关注A的所有用户}称为(A,电影)的圈子
现需要实现与圈子相关的功能。
上一版中说“此题关键是查表,关注链与被关注链一定要分开!!”
其实后来发现,话说的没错,本质是个图的广度优先搜索!!思路是:关注链和被关注链一定要分开处理,用一个数组记录所有关注关系,
数组的每个元素是一条关注关系。为了提高效率(否则TEL)和增加迭代结束条件,每条关系增加一个标记(非常好的点子)。
另外,添加用户和添加关系、计算圈子用户数没有耦合在一块。从做题角度讲还可以, 从系统设计角度讲应该抽象出共同的东西。
#include "GetUserNum.h" #include <vector> #include <map> #include <set> #include <algorithm> using namespace std; typedef enum tagTraverseFlag { INIT = 0, IS_TRAVERSE }TRAVERSEFLAG; typedef struct tagFollowRelation { unsigned int userId;//指定用户 unsigned int followerId;//关注userId的用户 unsigned int hobbyId; TRAVERSEFLAG traverseFlag; }FollowRelation; vector<FollowRelation> followRelationVec; map<unsigned int, vector<unsigned int> > userHobbysMap; //set<unsigned int> followingSet; //set<unsigned int> followedSet; set<unsigned int> circleSet; vector<FollowRelation> tempFrVec; /****************************************************************************** 功能: 增加用户 输入参数: user_id : 增加的用户 hobby_num: 此用户的爱好个数 hobby_array: 此用户的爱好数组 返回值:无 *******************************************************************************/ void AddUser(unsigned int user_id, unsigned int hobby_num, const unsigned int hobby_array[]) { vector<unsigned int> hobbyArray; for(unsigned int i = 0; i < hobby_num; i++) { hobbyArray.push_back(hobby_array[i]); } userHobbysMap.insert(pair<unsigned int,vector<unsigned int> >(user_id, hobbyArray)); return; } //检测指定的用户是否存在,如果存在继续判断指定的用户是否有指定的爱好,不存在返回-1 int isExistCheck(unsigned int user_id, unsigned int hobby_id) { if(userHobbysMap.count(user_id) == 0) { return -1; } else if(find(userHobbysMap[user_id].begin(), userHobbysMap[user_id].end(), hobby_id) == userHobbysMap[user_id].end()) { return -1; } return 0; } /****************************************************************************** 功能: 增加关注相关信息 输入参数: user_id: 指定用户 follower_id : 关注user_id的用户 hobby_id: 爱好 返回值: 成功,返回0 失败, 返回-1。 *******************************************************************************/ int AddFollowInfo( unsigned int user_id, unsigned int follower_id, unsigned int hobby_id ) { //检测输入参数是否存在 if(isExistCheck(user_id, hobby_id) == -1 || isExistCheck(follower_id, hobby_id) == -1) { return -1; } //follower_id与user_id相同 if(user_id == follower_id) { return -1; } //“user_id、 follower_id、hobby_id”全部相同的关注信息已经存在。 if(!followRelationVec.empty()) { vector<FollowRelation>::iterator iter = followRelationVec.begin(); for(; iter != followRelationVec.end(); iter++) { if(iter->userId == user_id && iter->followerId == follower_id && iter->hobbyId == hobby_id) { return -1; } } } FollowRelation followRelation = {0, 0, 0, INIT}; followRelation.userId = user_id; followRelation.followerId = follower_id; followRelation.hobbyId = hobby_id; followRelation.traverseFlag = INIT; followRelationVec.push_back(followRelation); return 0; }