Design Twitter 面向对象设计 优先队列 HashMap

àì夳堔傛蜴生んèń 2023-11-12 00:45 217阅读 0赞

应用面向对象设计(OO)模拟Twitter的几个功能,分别是:

  1. 发推postTweet(userId, tweetId): Compose a new tweet.
  2. 获取最近的十条推文getNewsFeed(userId): Retrieve the 10 most recent tweet ids in the user’s news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent.
  3. 关注follow(followerId, followeeId): Follower follows a follow.
  4. 取关unfollow(followerId, followeeId): Follower unfollows a followee

首先要考虑的是,这里应该有用户、推文,用户很简单,一个整形就可以表示。推文需要有,userId,tweetId,timestamp(我们这里并不需要详细的时间,只要有每条推文的先后顺数就可以了),对此我们使用struct tweet
接下来分析功能,每一个用户都应该有一个数组来记录他的关注对象,另外一个数组纪录他的推文,这里可以选择建一个structure记录这些数据,但是在这道题里我们只用到了两个unordered_maps存放对应数据,在map中每个整形(userId)都有对应的followees和tweets
有了这样的数据结构呢,postTweet, follow, unfollow都很好实现了,只需要对map进行相应操作即可。
有些难得是getNewsFeed这个函数,返回用户关注的最近十条推文,包括他自己的。对于这种有顺序的东西很容易想到priority_queue, 下面这个solution用一个priority-queue存储该用户关注的每个用户的推文的begin iterator, end iterator. begin iterator用于从每个follow发的最新的推文中选出最新的。

  1. class Twitter {
  2. private:
  3. struct tweet {
  4. int userId;
  5. int tweetId;
  6. int timesStamp;
  7. tweet(int x, int y, int z): userId(x), tweetId(y), timesStamp(z){};
  8. };
  9. struct mycompare {
  10. bool operator()(pair<list<tweet>::iterator, list<tweet>::iterator> p1,
  11. pair<list<tweet>::iterator, list<tweet>::iterator> p2) {
  12. return p1.first->timesStamp < p2.first->timesStamp;
  13. }
  14. };
  15. int timeLabel = 0;
  16. unordered_map<int, unordered_set<int>> followees;
  17. unordered_map<int, list<tweet>> tweets;
  18. public:
  19. /** Initialize your data structure here. */
  20. Twitter() {}
  21. /** Compose a new tweet. */
  22. void postTweet(int userId, int tweetId) {
  23. followees[userId].insert(userId);
  24. tweets[userId].push_front(tweet(userId, tweetId, timeLabel));
  25. timeLabel++;
  26. }
  27. /** Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. */
  28. vector<int> getNewsFeed(int userId) {
  29. vector<int> res;
  30. if (followees.find(userId) == followees.end()) return res;
  31. priority_queue<pair<tweet, tweet>,
  32. vector<pair<tweet, tweet>>,
  33. mycompare> pq;
  34. for (auto it = followees[userId].begin(); it != followees[userId].end(); it++)
  35. if (tweets[*it].begin() != tweets[*it].end())
  36. pq.push(make_pair(* tweets[*it].begin(), * tweets[*it].end()));
  37. int index = 0;
  38. while(!pq.empty() && index < 10) {
  39. auto tmp = pq.top();
  40. pq.pop();
  41. res.push_back(tmp.first.tweetId);
  42. if (++tmp.first != tmp.second)
  43. pq.push(tmp);
  44. index++;
  45. }
  46. return res;
  47. }
  48. /** Follower follows a followee. If the operation is invalid, it should be a no-op. */
  49. void follow(int followerId, int followeeId) {
  50. followees[followerId].insert(followerId);
  51. followees[followerId].insert(followeeId);
  52. }
  53. /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */
  54. void unfollow(int followerId, int followeeId) {
  55. if (followees.find(followerId) != followees.end() && followerId != followeeId) {
  56. followees[followerId].erase(followeeId);
  57. }
  58. }
  59. };
  60. /**
  61. * Your Twitter object will be instantiated and called as such:
  62. * Twitter obj = new Twitter();
  63. * obj.postTweet(userId,tweetId);
  64. * vector<int> param_2 = obj.getNewsFeed(userId);
  65. * obj.follow(followerId,followeeId);
  66. * obj.unfollow(followerId,followeeId);
  67. */

class Twitter {
private:
unordered_map> user;
vector> tweet;
public:
/** Initialize your data structure here. */
Twitter() {

}

/** Compose a new tweet. */
void postTweet(int userId, int tweetId) {
tweet.push_back(make_pair(userId,tweetId));
}

/** Retrieve the 10 most recent tweet ids in the user’s news feed. */
vector getNewsFeed(int userId) {
vector ret;
for(int i=tweet.size()-1; i>=0; —i){
if(userId == tweet[i].first || user[userId].find(tweet[i].first) != user[userId].end()){
ret.push_back(tweet[i].second);
}
if((int)ret.size() == 10) break;
}
return ret;
}

/** Follower follows a followee. If the operation is invalid, it should be a no-op. */
void follow(int followerId, int followeeId) {
user[followerId].insert(followeeId);
}

/** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */
void unfollow(int followerId, int followeeId) {
user[followerId].erase(followeeId);
}
};

发表评论

表情:
评论列表 (有 0 条评论,217人围观)

还没有评论,来说两句吧...

相关阅读

    相关 队列优先队列

    队列 队列是一种特殊的[线性表][Link 1],特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作

    相关 优先队列

    优先队列:顾名思义,首先它是一个队列,但是它强调了“优先”二字,所以,已经不能算是一般意义上的队列了,它的“优先”意指取队首元素时有一定的选择性,即根据元素的属性选择某一项值最

    相关 面向对象设计

    面向对象设计 1.了解面向对象设计的特点 1.信息隐藏和封装特性: 封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世

    相关 优先队列

    [为什么80%的码农都做不了架构师?>>> ][80_] ![hot3.png][] 优先队列是不同于先进先出队列的另一种队列。每次从队列中取出的是具有最高优先权的元素。