Skip to content

387. First Unique Character in a String#18

Open
fhiyo wants to merge 2 commits intomainfrom
387_first-unique-character-in-a-string
Open

387. First Unique Character in a String#18
fhiyo wants to merge 2 commits intomainfrom
387_first-unique-character-in-a-string

Conversation

@fhiyo
Copy link
Copy Markdown
Owner

@fhiyo fhiyo commented Jun 6, 2024

unique_occurrence_indexes = {} # 2回以上出現した場合はlen(s)が入る
for i, c in enumerate(s):
if c in unique_occurrence_indexes:
unique_occurrence_indexes[c] = len(s)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

2回以上出現した際の値のマーカーとしてはlen(s)以上の値なら何でもよいのかと思いますが、特定の数値だとその数値に何か意味があるのかなと思ってしまいそうだなと感じました。min(a,b)の単位元がinfなので個人的にはinfにするのがわかりやすいと思いました。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

変数を grue や bleen のようにしない
https://discord.com/channels/1084280443945353267/1192736784354918470/1194530857902419978

first_zero を自然言語で表現するとなんですかね。
「はじめの0が出てくるまでは、i か i + 1 を指していて、0が出てくると、そこで止まり、swap する関係上、そこから先は常にはじめの0を指している。」
https://discord.com/channels/1084280443945353267/1192736784354918470/1199760331824713758

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

これ、この変数を一言で説明するとなんですかね。
unique_occurrence_indexes は、「文字をキーとし、バリューは、はじめに出てきたインデックスであるが、2回以上出現した場合には len(s) が入っている dict」ですよね。

それだったら「文字とそのはじめの出現位置の dict」「2回以上出現した文字の set」の二変数を持ったほうが素直ですよね。

自然言語で説明すると複雑な変数は分けましょう。私は、grue や bleen みたいなものだと思っています。
https://en.wikipedia.org/wiki/New_riddle_of_induction

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

2回以上出現した際の値のマーカーとしてはlen(s)以上の値なら何でもよいのかと思いますが、特定の数値だとその数値に何か意味があるのかなと思ってしまいそうだなと感じました。min(a,b)の単位元がinfなので個人的にはinfにするのがわかりやすいと思いました。

indexを入れる辞書にfloatが入る気持ち悪さを優先してlen(s)を選択した感じでした。単位元がinfだから自然というのはなるほどと思いました

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

問題に対してオーバーキルではありますが、意味が分かりやすい変数だと、unordered_map<char, vector<int>> char_to_indicesunordered_map<char, int> first_indexunordered_map<char, int> char_countなどといった選択肢がありそうですね。

```py
class Solution:
def firstUniqChar(self, s: str) -> int:
unique_occurrence_indexes = {} # 2回以上出現した場合はlen(s)が入る
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

OrderedDictというのもあるので見ておくといいと思います。
https://docs.python.org/ja/3/library/collections.html#collections.OrderedDict

OrderedDictとsetを組み合わせて解けます。

class DefaultDict(dict):
def __init__(self, default_factory=None):
self.default_factory = default_factory

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

質問ぽい感じになるのですが、継承する時ってsuper().init()を書かなくて良いのでしょうか。
そこまで神経質にならなくてもいいのでしょうか。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

あまり自信ないんですが、考えてみると書いた方がいい気がしました。下のような動きになるので。

$ ipython
Python 3.11.3 (main, Jun  5 2023, 00:49:13) [Clang 14.0.3 (clang-1403.0.22.14.1)]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.14.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: class DefaultDict(dict):
   ...:   def __init__(self, default_factory=None):
   ...:     self.default_factory = default_factory
   ...:
   ...:   def __missing__(self, key):
   ...:     if self.default_factory is None:
   ...:       raise KeyError
   ...:     self[key] = self.default_factory()
   ...:     return self[key]
   ...:

In [2]: d = DefaultDict(list, a=10)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[2], line 1
----> 1 d = DefaultDict(list, a=10)

TypeError: DefaultDict.__init__() got an unexpected keyword argument 'a'

In [3]: from collections import defaultdict

In [4]: d2 = defaultdict(list, a=10) # 例外は起こらない

こんな感じに書けばいいかもですね。↓

In [5]: class DefaultDict(dict):
   ...:   def __init__(self, default_factory=None, *args, **kwargs):
   ...:     super().__init__(*args, **kwargs)
   ...:     self.default_factory = default_factory
   ...:
   ...:   def __missing__(self, key):
   ...:     if self.default_factory is None:
   ...:       raise KeyError
   ...:     self[key] = self.default_factory()
   ...:     return self[key]
   ...:

In [6]: d3 = DefaultDict(list, a=10) # 例外は起こらない

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

なるほど、おそらくdictクラスの方でなんかしらの初期化変数が実はあるんですね。
書き方も参考になりました。

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.

6 participants