-
Notifications
You must be signed in to change notification settings - Fork 0
LeetCode 200. Number of Islands #40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| class Solution { | ||
| public: | ||
| int numIslands(const std::vector<std::vector<char>>& grid) { | ||
| constexpr char kWater = '0'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
numIslandsの内部ではなく、Solution のメンバとして宣言する、という選択肢もありそうでした(Solution=問題で与えられた定数ですよね)。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Solutionという抽象的なクラス名なので、複数の問題への解答を持つ可能性もあるかな...と考え numIslandsに関連するものは全て中に置きたい気持ちがあったのですが、考えすぎだったかもしれません。ありがとうございます!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Solutionという抽象的なクラス名なので、複数の問題への解答を持つ可能性もあるかな...と考え
この想定は思いつきませんでした。それはそれで一貫性があるので問題ないと思います!
| std::queue<std::pair<int, int>> area_to_visit; | ||
| area_to_visit.push({row, col}); | ||
| while (!area_to_visit.empty()) { | ||
| auto [r, c] = area_to_visit.front(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
個人的には、スコープも狭いし、直前で row, col をpushしていることから、r, c でも読めました。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
フィードバックいただきありがとうございます。自分以外からどう見えるかのサンプルが増えて助かります。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
同じく,直前のrow, colのpushにより意図はすぐ読み取れました.
| std::queue<std::pair<int, int>> area_to_visit; | ||
| area_to_visit.push({row, col}); | ||
| while (!area_to_visit.empty()) { | ||
| auto [visiting_row, visiting_col] = area_to_visit.front(); | ||
| area_to_visit.pop(); | ||
| if (visiting_row < 0 || num_rows <= visiting_row || | ||
| visiting_col < 0 || num_cols <= visiting_col) { | ||
| continue; | ||
| } | ||
| if (grid[visiting_row][visiting_col] == kWater) { continue; } | ||
| if (visited[visiting_row][visiting_col]) { continue; } | ||
|
|
||
| area_to_visit.push({visiting_row + 1, visiting_col}); | ||
| area_to_visit.push({visiting_row - 1, visiting_col}); | ||
| area_to_visit.push({visiting_row, visiting_col + 1}); | ||
| area_to_visit.push({visiting_row, visiting_col - 1}); | ||
| visited[visiting_row][visiting_col] = true; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
好みの範囲ですが、自分ならここをサブルーチンに切り出します。理由としては「未訪問のセルをvisitedとしてマークしてるんだよ」という、forループの中の大半を占める処理(かつ境界判定など細かい処理を含む)が、サブルーチンの名前として要約できるからです。デメリットは関数を呼ぶオーバーヘッドや、num_{rows,cols} を取り出し直したり、grid などを引き回したりする手間があることです。
ちなみにC++詳しくないのですが、コンパイル時に展開することでオーバーヘッドを無くせたりしませんでしたっけ。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ありがとうございます。ここのやや複雑な処理を抽象度高くまとめてしまえば 全体としてnumIslandsが何をするのか頭に収まりやすくなりそうですね。
また、コンパイル時の最適化により関数呼び出しのオーバーヘッドをなくすことができるのを知りませんでした、ありがとうございます。確かに、コンパイル時に最適化を有効にすれば
関数をそのまま呼び出し側に展開して呼び出しのオーバーヘッドを避けることができるようです。
| class Solution { | ||
| public: | ||
| int numIslands(std::vector<std::vector<char>>& grid) { | ||
| const int kWater = '0'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
定数は static なメンバ変数か、グローバルに定義することが多いように思います。
| public: | ||
| int numIslands(std::vector<std::vector<char>>& grid) { | ||
| const int kWater = '0'; | ||
| const int num_rows = (int)grid.size(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static_cast() でキャストしたほうが C++ っぽく感じるのですが、やりすぎかもしれません。チームの平均的な書き方に合わせることをお勧めいたします。
参考までにスタイルガイドへのリンクを共有いたします。
https://google.github.io/styleguide/cppguide.html#Casting
Use C++-style casts like static_cast(double_value), or brace initialization for conversion of arithmetic types like int64_t y = int64_t{1} << 42. Do not use cast formats like (int)x unless the cast is to void.
なお、このスタイルガイドは“唯一の正解”というわけではなく、数あるガイドラインの一つに過ぎません。チームによって重視される書き方や慣習も異なります。そのため、ご自身の中に基準を持ちつつも、最終的にはチームの一般的な書き方に合わせることをお勧めします。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
リファレンスまでいただきありがとうございます!
| public: | ||
| int numIslands(std::vector<std::vector<char>>& grid) { | ||
| const int kWater = '0'; | ||
| const int num_rows = (int)grid.size(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
個人的にはプリミティブ型のローカル変数には const を付けないのですが、趣味の範囲だと思います。所属するチームの平均的な書き方に合わせることをお勧めいたします。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
横から失礼します。
個人的にはプリミティブ型のローカル変数には const を付けない
C++に詳しくないのですが、この趣味の背景を知りたいです。多少視覚のノイズにはなるものの、中身を変えるつもりがないなら const を付けておいたほうが安全に思う(し、そうであることを読み手にも伝えられると思う)のですが、どういう取捨選択なのか教えていただけますか。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
非常に個人的な体験からなのですが、ほかの方から「const 教」と揶揄されたためです。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
基本的に文字数が増える以外つけて損はないんですけども、たとえば3行しかスコープのない変数には const とつけなくても変更がないことが明らかだろと、言いたい人はいるんじゃないですかね。
|
|
||
| ++num_islands; | ||
|
|
||
| std::queue<std::tuple<int, int>> area_to_explore; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
座標を表す構造体を定義し、それを push() していったほうが、読み手にとって分かりやすいかもしれません。ただ、大げさすぎるように思います。
| auto [r, c] = area_to_explore.front(); | ||
| area_to_explore.pop(); | ||
|
|
||
| if (r < 0 || num_rows <= r || c < 0 || num_cols <= c) { continue; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
r と c が視覚的にまとまるよう、
if (!(0 <= r && r < num_rows && 0 <= c && c < num_cols))と書いたほうが分かりやすいと思います。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
確かにそうですね、ありがとうございます!
| } | ||
|
|
||
| visited[row][col] = true; | ||
| const std::tuple<int, int> directions[4] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
staticなメンバ変数として定義して良いと思いました.
| std::queue<std::pair<int, int>> area_to_visit; | ||
| area_to_visit.push({row, col}); | ||
| while (!area_to_visit.empty()) { | ||
| auto [r, c] = area_to_visit.front(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
同じく,直前のrow, colのpushにより意図はすぐ読み取れました.
| area_to_visit.push({r + 1, c}); | ||
| area_to_visit.push({r - 1, c}); | ||
| area_to_visit.push({r, c + 1}); | ||
| area_to_visit.push({r, c - 1}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
好みだとは思いますがforで回す方が読みやすかったです.
https://leetcode.com/problems/number-of-islands/description/