From 9606d3437f148a32236fd55342faedb9b40994d6 Mon Sep 17 00:00:00 2001 From: Victor Wu Date: Wed, 11 Nov 2020 13:37:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=BA=E8=AE=BE=E8=AE=A1Twitter=E4=B8=80?= =?UTF-8?q?=E6=96=87=EF=BC=8C=E5=AE=9E=E7=8E=B0C++=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 严格遵守框架。时间戳改成全局变量,并分模块拆开写(参照Java思路) --- .../\350\256\276\350\256\241Twitter.md" | 119 +++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-) diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204\347\263\273\345\210\227/\350\256\276\350\256\241Twitter.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204\347\263\273\345\210\227/\350\256\276\350\256\241Twitter.md" index 399fbbb..5f6c5f5 100644 --- "a/\346\225\260\346\215\256\347\273\223\346\236\204\347\263\273\345\210\227/\350\256\276\350\256\241Twitter.md" +++ "b/\346\225\260\346\215\256\347\273\223\346\236\204\347\263\273\345\210\227/\350\256\276\350\256\241Twitter.md" @@ -302,4 +302,121 @@ PS:本文前两张图片和 GIF 是我第一次尝试用平板的绘图软件

-======其他语言代码====== \ No newline at end of file +======其他语言代码====== + +[happy-yuxuan](https://github.com/happy-yuxuan) 提供 C++ 代码: + +```c++ +static int timestamp = 0; +class Tweet { +private: + int id; + int time; +public: + Tweet *next; + // id为推文内容,time为发文时间 + Tweet(int id, int time) { + this->id = id; + this->time = time; + next = nullptr; + } + int getId() const { + return this->id; + } + int getTime() const { + return this->time; + } +}; +class User { +private: + int id; +public: + Tweet *head; // 发布的Twitter,用链表表示 + unordered_set followed; // 用户关注了那些人 + User(int userId) { + this->id = userId; + head = nullptr; + // 要先把自己关注了 + followed.insert(id); + } + void follow(int userId) { + followed.insert(userId); + } + void unfollow(int userId) { + // 不可以取关自己 + if (userId != this->id) + followed.erase(userId); + } + void post(int contentId) { + Tweet *twt = new Tweet(contentId, timestamp); + timestamp++; + // 将新建的推文插入链表头 + // 越靠前的推文 timestamp 值越大 + twt->next = head; + head = twt; + } +}; +class Twitter { +private: + // 映射将 userId 和 User 对象对应起来 + unordered_map userMap; + // 判断该用户存不存在系统中,即userMap中存不存在id + inline bool contain(int id) { + return userMap.find(id) != userMap.end(); + } +public: + Twitter() { + userMap.clear(); + } + /* user 发表一条 tweet 动态 */ + void postTweet(int userId, int tweetId) { + if (!contain(userId)) + userMap[userId] = new User(userId); + userMap[userId]->post(tweetId); + } + /* 返回该 user 关注的人(包括他自己)最近的动态 id, + 最多 10 条,而且这些动态必须按从新到旧的时间线顺序排列。*/ + vector getNewsFeed(int userId) { + vector ret; + if (!contain(userId)) return ret; + // 构造一个自动通过Tweet发布的time属性从大到小排序的二叉堆 + typedef function Compare; + Compare cmp = [](const Tweet *a, const Tweet *b) { + return a->getTime() < b->getTime(); + }; + priority_queue, Compare> q(cmp); + // 关注列表的用户Id + unordered_set &users = userMap[userId]->followed; + // 先将所有链表头节点插入优先级队列 + for (int id : users) { + if (!contain(id)) continue; + Tweet *twt = userMap[id]->head; + if (twt == nullptr) continue; + q.push(twt); + } + while (!q.empty()) { + Tweet *t = q.top(); q.pop(); + ret.push_back(t->getId()); + if (ret.size() == 10) return ret; // 最多返回 10 条就够了 + if (t->next) + q.push(t->next); + } + return ret; + } + /* follower 关注 followee */ + void follow(int followerId, int followeeId) { + // 若 follower 不存在,则新建 + if (!contain(followerId)) + userMap[followerId] = new User(followerId); + // 若 followee 不存在,则新建 + if (!contain(followeeId)) + userMap[followeeId] = new User(followeeId); + userMap[followerId]->follow(followeeId); + } + /* follower 取关 followee,如果 Id 不存在则什么都不做 */ + void unfollow(int followerId, int followeeId) { + if (contain(followerId)) + userMap[followerId]->unfollow(followeeId); + } +}; +``` \ No newline at end of file -- GitLab