-
Notifications
You must be signed in to change notification settings - Fork 0
2. add two numbers #5
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?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| レビューの利便性のため、各ステップで書いたコードはこちらにも転記してみます。 | ||
|
|
||
| # step1 | ||
| 元のリストに対して非破壊的であるようにしたい。素直に繰り上がりを記録しながら足していく方針で解いた。 | ||
| ```cpp | ||
| class Solution { | ||
| public: | ||
| ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { | ||
| ListNode dummy(0, nullptr); | ||
| ListNode* tail = &dummy; | ||
| int carry = 0; | ||
| while (l1 != nullptr || l2 != nullptr || carry != 0) { | ||
| int val = (l1 ? l1->val : 0) + (l2 ? l2->val : 0) + carry; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 好みの問題ですが、個人的にはこちらの方が読みやすいと思いました。 int digit1 = l1 ? l1->val : 0;
int digit2 = l2 ? l2->val : 0;
int val = digit1 + digit2 + carry;
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. コメントありがとうございます。おっしゃる通り今の場合ぱっと見で分けたほうが何をやっているかわかりやすいですね。 |
||
| carry = val / 10; | ||
| ListNode* append = new ListNode(val % 10, nullptr); | ||
| tail->next = append; | ||
| l1 = l1 ? l1->next : nullptr; | ||
| l2 = l2 ? l2->next : nullptr; | ||
| tail = tail->next; | ||
| } | ||
| return dummy.next; | ||
| } | ||
| }; | ||
| ``` | ||
|
|
||
| # step2 | ||
| 他の人のコードを見る。 | ||
| - [ryosuketcさんのコード](https://github.com/ryosuketc/leetcode_arai60/blob/2_add_two_numbers/2_add_two_numbers/step3.py)と本質的に同じだがこちらのほうが丁寧に関数や定数を切り出している。 | ||
| - 他の演算も実装する必要があったら補助関数を設定すると思う。 | ||
| - 他のコメントでも三項演算子は避けられているようだが、今回のようなnullでないことだけ判定するくらいなら左から右に読みやすいと思うので許されたい… | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Python の三項演算子が A if condition else B というもので分かりにくいんですよね。 C++ はまだましだと思いますが、しかし、使ってきれいになることは実は少ないと思います。 |
||
| - l1, l2がnullptrだったときだけ使うfakeを置いたら場合分けする部分が集約できた。 | ||
|
|
||
| ```cpp | ||
| class Solution { | ||
| public: | ||
| ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { | ||
| ListNode dummy(-1, nullptr); | ||
| ListNode* tail = &dummy; | ||
| int carry = 0; | ||
| while (l1 || l2 || carry) { | ||
| // l1, l2がnullptrだった場合0ノードを一時的に設定する。このブロックを抜けると解放される。 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. なるほど、こうした fake を置くという発想はありませんでした (私も …と思ってよい名前を少し考えましたが意外に思いつきませんでした。 |
||
| ListNode fake(0); | ||
| l1 = l1 ? l1 : &fake; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ぶら下がりでも良ければ下の方が意図がはっきりしていませんか? l1 = l1 ? l1 : &fake;
if (!l1) l1 = &fake;
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. どちらが分かりやすいかと言われれば後者ですね…コードゴルフでもないので人が読むコードでは避けようと思います。 |
||
| l2 = l2 ? l2 : &fake; | ||
|
|
||
| int total = l1->val + l2->val + carry; | ||
| carry = total / 10; | ||
| tail->next = new ListNode(total % 10, nullptr); | ||
| tail = tail->next; | ||
| l1 = l1->next; | ||
| l2 = l2->next; | ||
| } | ||
| return dummy.next; | ||
| } | ||
| }; | ||
|
|
||
| ``` | ||
|
|
||
| # step3 | ||
| fakeをwhileの外においてみた。 | ||
| ```cpp | ||
| class Solution { | ||
| public: | ||
| ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { | ||
| ListNode dummy = ListNode(-1); | ||
| ListNode* tail = &dummy; | ||
| int carry = 0; | ||
|
|
||
| ListNode fake = ListNode(0); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 外に出すならば const をより付けたいですね。 |
||
| while (l1 || l2 || carry) { | ||
| l1 = l1 ? l1 : &fake; | ||
| l2 = l2 ? l2 : &fake; | ||
| int total = l1->val + l2->val + carry; | ||
| carry = total / 10; | ||
| tail->next = new ListNode(total % 10); | ||
|
|
||
| tail = tail->next; | ||
| l1 = l1->next; | ||
| l2 = l2->next; | ||
| } | ||
| return dummy.next; | ||
| } | ||
| }; | ||
| ``` | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| struct ListNode { | ||
| int val; | ||
| ListNode* next; | ||
| ListNode() : val(0), next(nullptr) {} | ||
| ListNode(int x) : val(x), next(nullptr) {} | ||
| ListNode(int x, ListNode* next) : val(x), next(next) {} | ||
| }; | ||
|
|
||
| class Solution { | ||
| public: | ||
| ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { | ||
| ListNode dummy(0, nullptr); | ||
| ListNode* tail = &dummy; | ||
| int carry = 0; | ||
| while (l1 != nullptr || l2 != nullptr || carry != 0) { | ||
| int val = (l1 ? l1->val : 0) + (l2 ? l2->val : 0) + carry; | ||
| carry = val / 10; | ||
| ListNode* append = new ListNode(val % 10, nullptr); | ||
| tail->next = append; | ||
| l1 = l1 ? l1->next : nullptr; | ||
| l2 = l2 ? l2->next : nullptr; | ||
| tail = tail->next; | ||
| } | ||
| return dummy.next; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| struct ListNode { | ||
| int val; | ||
| ListNode* next; | ||
| ListNode() : val(0), next(nullptr) {} | ||
| ListNode(int x) : val(x), next(nullptr) {} | ||
| ListNode(int x, ListNode* next) : val(x), next(next) {} | ||
| }; | ||
|
|
||
| class Solution { | ||
| public: | ||
| ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { | ||
| ListNode dummy(-1, nullptr); | ||
| ListNode* tail = &dummy; | ||
| int carry = 0; | ||
| while (l1 || l2 || carry) { | ||
| // l1, l2がnullptrだった場合0ノードを一時的に設定する。このブロックを抜けると解放される。 | ||
| ListNode fake(0); | ||
| l1 = l1 ? l1 : &fake; | ||
| l2 = l2 ? l2 : &fake; | ||
|
|
||
| int total = l1->val + l2->val + carry; | ||
| carry = total / 10; | ||
| tail->next = new ListNode(total % 10, nullptr); | ||
| tail = tail->next; | ||
| l1 = l1->next; | ||
| l2 = l2->next; | ||
| } | ||
| return dummy.next; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| struct ListNode { | ||
| int val; | ||
| ListNode* next; | ||
| ListNode() : val(0), next(nullptr) {} | ||
| ListNode(int x) : val(x), next(nullptr) {} | ||
| ListNode(int x, ListNode* next) : val(x), next(next) {} | ||
| }; | ||
|
|
||
| class Solution { | ||
| public: | ||
| ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { | ||
| ListNode dummy = ListNode(-1); | ||
| ListNode* tail = &dummy; | ||
| int carry = 0; | ||
|
|
||
| ListNode fake = ListNode(0); | ||
| while (l1 || l2 || carry) { | ||
| l1 = l1 ? l1 : &fake; | ||
| l2 = l2 ? l2 : &fake; | ||
| int total = l1->val + l2->val + carry; | ||
| carry = total / 10; | ||
| tail->next = new ListNode(total % 10); | ||
|
|
||
| tail = tail->next; | ||
| l1 = l1->next; | ||
| l2 = l2->next; | ||
| } | ||
| return dummy.next; | ||
| } | ||
| }; |
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.
下の方の2行と合わせて、これも候補でしょう。(どちらがいいというわけではなく。)
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.
ありがとうございます。こちらも意図がわかりやすいですね。