Skip to content

Create Unique Email Addresses.md #4

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions Unique Email Addresses/Unique Email Addresses.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Step1
何も見ずに実行
```python
class Solution:
def numUniqueEmails(self, emails: List[str]) -> int:
valid_emails = []
for email in emails:
local, domain = email.split("@")
local = local.replace(".", "")
local = local.split("+")[0]
email = local+"@"+domain
Copy link

@huyfififi huyfififi May 23, 2025

Choose a reason for hiding this comment

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

私はf-stringの方が結果の文字列が想像しやすくて好きです。Googleのスタイルガイドにも、

Use an f-string...(中略)...A single join with + is okay but do not format with +.
No: x = first + ', ' + second

とあり、私個人は、スタイルガイドにあるということは多くの人がf-stringの方を好ましく思うのだろう、と想定しています。

Copy link

@tokuhirat tokuhirat May 23, 2025

Choose a reason for hiding this comment

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

書き方として email = f"{local}@{domain}" というパターンもありますね。
https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals

if email not in valid_emails:
valid_emails.append(email)
return len(valid_emails)
```
emailをlocalとdomainに分割し,ルールに従い,domainを実際に有効な形式に変換した.単純にリストにappendして数えたが,dictを使ったらより計算効率が上がるかもしれない.

# Step2
他の人の解答を参照する.
https://github.com/potrue/leetcode/pull/14/files#diff-6a8efe56493bdbfeb045b7aa123660406ebdd5dd4f0a011935562d4eefb9ab46

上記を見ると,概ね実装方針は同じだった.ただ,以下が参考になった.

Choose a reason for hiding this comment

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

1文字ずつ処理する方法も選択肢として持って良いと思います!

- listの代わりにset()を使っていたこと.setは重複を排除する.

Choose a reason for hiding this comment

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

要素数 n の list では in は O(n) かかります。set の場合は O(1) という違いもあります。
https://wiki.python.org/moin/TimeComplexity

- @が含まれない場合も考慮して,partitionを使用していたこと.partitionは区切り文字も返す.
Copy link

@tokuhirat tokuhirat May 23, 2025

Choose a reason for hiding this comment

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

Step3では、@ が含まれない場合、全体を local として受け入れて処理する方針になっていますね。

Copy link
Owner Author

Choose a reason for hiding this comment

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

そういう意味だったのですね.誤った認識をしてました.ご指摘ありがとうございます.


また,RFC規格という存在を知った.https://info.yamap.com/archives/3434

Choose a reason for hiding this comment

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

私も間違った認識をしていましたが、 RFCは規格ではないようです.

rinost081/LeetCode#13 (comment)

Copy link
Owner Author

Choose a reason for hiding this comment

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

規格ではなく,文書ということですね.


Copy link

Choose a reason for hiding this comment

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

Copy link
Owner Author

Choose a reason for hiding this comment

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

初めて正規表現の概念を知りました.正規表現を使って解き直してみます.ありがとうございます.

# Step3
他の人の解答を参考に解き直す
```python
class Solution:
def numUniqueEmails(self, emails: List[str]) -> int:
valid_emails = set()
for email in emails:
local, at, domain = email.partition("@")
local = local.replace(".", "")
local = local.split("+")[0]

Choose a reason for hiding this comment

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

先に無視される部分を決めた方が(+の処理を先に行う)効率的ではないでしょうか。

Copy link
Owner Author

Choose a reason for hiding this comment

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

仰るとおりですね.ありがとうございます.

email = local + at + domain

Choose a reason for hiding this comment

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

partitionするときにlist型で取っておいてjoinすることもできそうですね

valid_emails.add(email)
return len(valid_emails)
```
# Step4
いただいたアドバイスを元に修正
```python
class Solution:
def numUniqueEmails(self, emails: List[str]) -> int:
valid_emails = set()
for email in emails:
local, at, domain = email.partition("@")
local = local.split("+")[0]
local = local.replace(".", "")
email = f"{local}@{domain}"
valid_emails.add(email)
return len(valid_emails)
```

正規表現を使って解き直してみる
```python
class Solution:
def numUniqueEmails(self, emails: List[str]) -> int:
valid_emails = set()
for email in emails:
local, domain = email.split('@')

Choose a reason for hiding this comment

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

re.matchやre.fullmatchあたりを使うこともできると思います
https://docs.python.org/ja/3.13/library/re.html#re.match

local = re.sub(r'\+.*', '', local)
local = re.sub(r'\.', '', local)
email = f'{local}@{domain}'
valid_emails.add(email)
return len(valid_emails)
```

- r'.'はすべての文字列を対象とする
- r'\.'は.自体を対象とする
- [\w\.-]+@[\w\.-]+\.\w+とするとemailアドレスの識別に使えるらしい.本問題では,localに.が2つある場合適用できないため,re.subで対応した