🎁 黑五优惠不停歇!VIP年通行证惊喜5折!蓝莓、Offer多多同步大放价! 🎁
<
查看: 8442| 回复: 37
收起左侧

[学C/C++] 分享几个C++刷题小技巧

   
烤馒头 | 显示全部楼层
本楼:   👍  24
89%
11%
3   👎
全局:   567
95%
5%
29

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
本帖最后由 烤馒头 于 2021-7-9 09:02 编辑

看隔壁问C++刷题有感,分享几个我从刷题中get的小技巧。有些非常好用甚至反哺到我工作当中。

1. 【初级】把count用做contain查看map/set/unordered_map/unordered_set里是否含有key
Before:
  1. if (keyValueMap.find(key) != keyValueMap.end()) {
  2.     ...
  3. }
复制代码

After:
  1. if (keyValueMap.count(key)) {    ...
  2. }
复制代码


2. 【中级】pair可以直接用auto取值或者取址
2.1 用于直观iterate map/unordered_map
Before:
  1. for (auto it = keyValueMap.begin(); it != keyValueMap.end(); it++) {
  2.     auto key = it->first;
  3.     auto value = it->second;
  4.     ...
  5. }
复制代码

After:
  1. for (auto& [key, value] : keyValueMap) {
  2.     ...
  3. }
复制代码


2.2 直角网格题遍历上下左右四个方向
After:
  1. vector<pair<int, int>> dirs {{0,1}, {1,0}, {0,-1}, {-1,0}};
  2. for (auto& [dx, dy] : dirs) {
  3.     int x = i + dx;
  4.     int y = j + dy;
  5.     ...
  6. }
复制代码


3. 【高级】可以用lambda function+capture &节省helper method要写的一堆input argument。例:LC 212
Before:
  1.     vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
  2.         auto root = buildTrie(words);
  3.         unordered_set<string> ans;
  4.         int m = board.size();
  5.         int n = board[0].size();

  6.         for (int i = 0; i < m; ++i) {
  7.             for (int j = 0; j < n; ++j) {
  8.                 dfs(board, m, n, ans, i, j, root);
  9.             }
  10.         }
  11.         ...
  12.     }
  13.     void dfs(vector<vector<char>>& board, int m, int n, unordered_set<string>& ans, int x, int y, TrieNode* node) {
  14.         ...
  15.         dfs(board, m, n, ans, x+1, y, node);
  16.         dfs(board, m, n, ans, x-1, y, node);
  17.         dfs(board, m, n, ans, x, y+1, node);
  18.         dfs(board, m, n, ans, x, y-1, node);
  19.         ...
  20.     }
复制代码


After:
  1.     vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
  2.         auto root = buildTrie(words);
  3.         unordered_set<string> ans;
  4.         int m = board.size();
  5.         int n = board[0].size();

  6.         function<void(int, int, TrieNode*)> dfs = [&](int x, int y, TrieNode* node) {
  7.             ...
  8.             for (auto& [dx, dy] : dirs) {
  9.                 dfs(x + dx, y + dy, node);
  10.             }
  11.             ...
  12.         };
  13.         
  14.         for (int i = 0; i < m; ++i) {
  15.             for (int j = 0; j < n; ++j) {
  16.                 dfs(i, j, root);
  17.             }
  18.         }
  19.         ...
  20.     }
复制代码

这里分享给大家,抛砖引玉。
如果感觉有用,欢迎加米,谢谢!



补充内容 (2021-07-10 13:18 +8:00):
经楼下提醒,我觉得有必要补充一下:第三个技巧仅限在OJ上刷题时使用(尤其参数特别多顺序容易错那种),可以非常清楚地列出来参与递归的参数。
但是建议
面试的时候谨慎使用!!
面试的时候谨慎使用!!
面试的时候谨慎使用!!
假如你不打招呼直接这么写,很有可能面试官看不懂,回头feedback给你个差评说你一个dfs非要用lambda,或者看懂了觉得你在炫技。得不偿失。
面试时还是乖乖把helper拎出来写比较好。

评分

参与人数 23大米 +80 收起 理由
不知道小帅 + 3 给你点个赞!
SilentPanda + 2 给你点个赞!
lyqk1998 + 2 给你点个赞!
zzxgz + 1 赞一个
錢霓 + 1 很有用的信息!

查看全部评分


上一篇:求分享力叩巨硬Explore里的题目
下一篇:有人一起读effective java吗?

本帖被以下淘专辑推荐:

feitao 2021-7-10 11:55:38 | 显示全部楼层
本楼:   👍  3
100%
0%
0   👎
全局:   16
64%
36%
9
1和3都是before比after好
回复

使用道具 举报

three0s 2021-7-10 11:42:39 | 显示全部楼层
本楼:   👍  3
100%
0%
0   👎
全局:   8
100%
0%
0
std::function会对性能有影响,可能会导致被多问问题,啥是type erasure blah blah。能写auto l = []() { ... }的话则没有这个影响(然后可以y-combinator递归...)。lamba的话[&]一般工作也不会这样写。。建议慎用

评分

参与人数 1大米 +1 收起 理由
烤馒头 + 1 确实仅在刷题时会用。谢谢提醒!

查看全部评分

回复

使用道具 举报

insomniadog 2021-7-10 12:55:11 | 显示全部楼层
本楼:   👍  2
100%
0%
0   👎
全局:   533
97%
3%
16
可能这些刷题能用 但是工作中这样写不一定就是好得。代码写的短!=代码写得好。

1 after 这样有个问题:一般对于元素是否包含得判断。都会跟一个如果含了这个元素 然后xxx得逻辑,
也就是说会变成

  1. if (keyValueMap.count(key)) {
  2. auto value = keyValueMap[key];
  3. ....
  4. }
复制代码

这样就是查找了两次了,还是老老实实用iterator吧。

3 after 存在得问题就是function body 太长。
如果让我来写,应该会尽量把逻辑拆开 多加helper function 也就是说反而是1 before更好. 这样至少有以下好处:
A. 能用命名表示这段得逻辑,虽然注释还是要写,但是一个好得命名函数也很重要。在主函数里面看一眼你得helper function,甚至都不用去读那一堆定义。
B. 能在函数声明得时候加各种宏定义,包括不限于const/锁 等。
C. 能复用




评分

参与人数 2大米 +4 收起 理由
14417335 + 3
烤馒头 + 1 谢谢你的分享!

查看全部评分

回复

使用道具 举报

troybitchen 2021-7-10 01:00:55 | 显示全部楼层
本楼:   👍  1
100%
0%
0   👎
全局:   327
98%
2%
8
前两个常用,第三个学习了
回复

使用道具 举报

 楼主| 烤馒头 2021-7-10 06:44:53 | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   567
95%
5%
29
troybitchen 发表于 2021-7-9 09:00
前两个常用,第三个学习了

第三个在OJ上做DFS/backtracking比较好用(比如要加visited那种),可以非常清楚地列出来参与递归的参数。
但是面试的时候建议谨慎使用,最好提前询问面试官,不然面试官可能看不懂,回头review说你一个dfs非要用lambda,或者看懂了觉得你炫技。。。
回复

使用道具 举报

應方 2021-7-10 07:01:52 来自APP | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   61
92%
8%
5
第三個是c++有別於c的進化之一,就是經過一學期的程式設計課後都還未使用就是🤣🤣。這篇好啊,希望更多大佬分享coding小技巧
回复

使用道具 举报

本楼:   👍  0
0%
0%
0   👎
全局:   25
100%
0%
0
第三个秀的呀!感谢
回复

使用道具 举报

dogeyy 2021-7-10 08:44:09 | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   82
100%
0%
0
第三个直接用auto关键字又可以偷一点懒hhh
回复

使用道具 举报

 楼主| 烤馒头 2021-7-10 09:04:40 来自APP | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   567
95%
5%
29
dogeyy 发表于 2021-07-09 17:44:09
第三个直接用auto关键字又可以偷一点懒hhh
如果你指的是lambda function定义,在写递归函数时不能用auto。
思考题:想想为什么?
回复

使用道具 举报

enthusiastic 2021-7-10 09:11:09 | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   28
85%
15%
5
mark了!很有用~不过我记得auto and lambda是cpp11的嘛,会不会存在面试官编译不了的情况啊(好像国内是会的)
回复

使用道具 举报

dogeyy 2021-7-10 09:18:35 | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   82
100%
0%
0
烤馒头 发表于 2021-7-10 09:04
如果你指的是lambda function定义,在写递归函数时不能用auto。
思考题:想想为什么?

原来如此,确实是我学艺不精hhh
回复

使用道具 举报

edwardifun 2021-7-10 10:24:40 | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   114
91%
9%
11
学习了。。谢谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表