Skip to content

232. Implement Queue using Stacks#13

Open
ryosuketc wants to merge 1 commit intomainfrom
232_implement_queue_using_stacks
Open

232. Implement Queue using Stacks#13
ryosuketc wants to merge 1 commit intomainfrom
232_implement_queue_using_stacks

Conversation

@ryosuketc
Copy link
Owner

Copy link

@nanae772 nanae772 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

お疲れ様です。C++は普段書かないのですが、コードを読ませていただき勉強になりました。読みやすく分かりやすいコードでした。
いくつかコメントさせていただいたので何か参考になりましたら幸いです。

* 久々に取り組んだ
* 問題文から、2 つ stack を使うことが明らかだったので、その方針で考えてみた。
* 一旦移して順番を入れ替える (reverse) はまあ思いついて、ただ O(n) なんだよな、と思いつつ、O(1) がないか 3:00 くらい考えたが思いつかなかった。
* `st`, `st_aux` よりはいい名前があるだろうと思ったが、あまり思いつかなかったのでこのまま
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

auxはauxiliary(補助)という意味の略称なんですね。
これは単なる質問なのですが、auxという略称はよく見かけられるのでしょうか?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aux はたまにみますが、私の考える典型例は下のような再帰のための補助関数ですね。

public:
  static Type Intersect(Type type1, Type type2, Zone* zone);
private:
  static int IntersectAux(Type type, Type other, UnionType* result, int size,
                          RangeType::Limits* limits, Zone* zone);

https://source.chromium.org/chromium/chromium/src/+/main:v8/src/compiler/turbofan-types.cc;l=814?q=aux%5Cb%20filepath:.*%5C.cc$

@@ -0,0 +1,54 @@
class MyQueue {
private:
// stack holds items in quque fashion.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

細かくて恐縮ですが、こちらqueueのスペルミスですかね

Comment on lines +11 to +14
if (st.empty()) {
st.push(x);
return;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここは無くてもいいのかなと思いました。
(追記)memoのほうでもご自分でも気づかれてましたね、失礼しました。

* 最初 `stack`, `stack_aux` としていたが、`std::stack` と衝突する
* 最初、`pop` の方で入れ替え処理を書こうとして、数行書いたあたりで、`pop` する処理と混ざって面倒なので、`push` で書いたほうがいいかな、と思った
* l11-14, 別になくても動くなと、後から読み直して気付いた
* 後から考えると、おそらく一般的なユースケースでは `pop` の方が頻度が低そうなので、そちらを O(n)、`push` を O(1) 二死したほうがよかったのかもしれない
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

こちらも単なる質問なのですが、こちらの「一般的なユースケースでは」というのは具体的にはどのようなユースケースを想定されておりましたか?
popの回数がpushの回数を上回らないというのは分かるのですが、私のイメージだとQueueを使うということはpush/popを同程度使うことが求められているのではないかという認識です。

Comment on lines +5 to +6
std::stack<int> stack_in;
std::stack<int> stack_out;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

分かりやすい名前で良いと思いました!
(自分はpush用のスタック、pop用のスタックでstack_push, stack_popとかにするかなと考えていました)


int pop() {
int front = peek();
stack_out.pop();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

peekのほうで例外が飛んでくる可能性があるのでそれをキャッチできるとよいのかなと思いました

* 久々に取り組んだ
* 問題文から、2 つ stack を使うことが明らかだったので、その方針で考えてみた。
* 一旦移して順番を入れ替える (reverse) はまあ思いついて、ただ O(n) なんだよな、と思いつつ、O(1) がないか 3:00 くらい考えたが思いつかなかった。
* `st`, `st_aux` よりはいい名前があるだろうと思ったが、あまり思いつかなかったのでこのまま
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aux はたまにみますが、私の考える典型例は下のような再帰のための補助関数ですね。

public:
  static Type Intersect(Type type1, Type type2, Zone* zone);
private:
  static int IntersectAux(Type type, Type other, UnionType* result, int size,
                          RangeType::Limits* limits, Zone* zone);

https://source.chromium.org/chromium/chromium/src/+/main:v8/src/compiler/turbofan-types.cc;l=814?q=aux%5Cb%20filepath:.*%5C.cc$

### step2

* https://leetcode.com/problems/implement-queue-using-stacks/editorial/
* amortized O(1) の書き方があるらしい。
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chris Okasaki の Purely Functional Data Structures に載ってますね。BankersQueue です。

* 最初、`pop` の方で入れ替え処理を書こうとして、数行書いたあたりで、`pop` する処理と混ざって面倒なので、`push` で書いたほうがいいかな、と思った
* l11-14, 別になくても動くなと、後から読み直して気付いた
* 後から考えると、おそらく一般的なユースケースでは `pop` の方が頻度が低そうなので、そちらを O(n)、`push` を O(1) 二死したほうがよかったのかもしれない
* `peek`, `pop` の empty check はメソッドにしてもいい
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Google Style だと名前の付け方として、

Accessors and mutators (get and set functions) may be named like variables, in snake_case.

です。empty, peek はいいとして、push, pop は先頭大文字かなとも思いますが、許される範囲かもしれません。
https://google.github.io/styleguide/cppguide.html#Function_Names

* 後から考えると、おそらく一般的なユースケースでは `pop` の方が頻度が低そうなので、そちらを O(n)、`push` を O(1) 二死したほうがよかったのかもしれない
* `peek`, `pop` の empty check はメソッドにしてもいい
* ただそれ以前に例外を投げていいのかちょっと迷った (https://github.com/ryosuketc/leetcode_grind75/pull/10#discussion_r2295004606)
* ただ今回だと int を返さなければならないが、"特殊な int" というのが思いつかなかった。どのような int でも queue に入る可能性があるので、特定の int をエラーとして扱うのは無理がある
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C++ は速度のために配列外アクセスは未定義動作にしてよいという風潮がありますが、まあ、空で pop したら例外を投げるほうが行儀はいいでしょうね。

std::stack<int> stack_out;
public:
MyQueue() {
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}
MyQueue() = default

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@austyhooong こちらのほうがいいと思った意図を書いてあげるとより好ましいと思います。

return stack_out.top();
}

bool empty() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bool empty() {
bool empty() const noexcept {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants