求圈子用户数_2.0

某网站,用户可按爱好关注其它用户。
相同爱好的关注可以传递:即如果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;
}
原文地址:https://www.cnblogs.com/liuzc/p/6552567.html