Closed16

1768. Merge Strings Alternately

yussakyussak

例を考える

ex1=>word1[0]word2[0]word1[1]word2[1]word1[2]word2[2]
ex2=>word1[0]word2[0]word1[1]word2[1]word2[2]word2[3]
ex3=>word1[0]word2[0]word1[1]word2[1]word1[2]word1[3]
yussakyussak

ex2を考える
短い方の長さmin_lengthとしてmin_length = 2
その時にi=0; i++; i<min_lengthに対してword1[i]+word2[i]
strに追加
i=0=>str=word1[0]+word2[0]
i=1=>str=上記のstr+word1[1]+word2[1] (str+=みたいにする)

長い方の長さmax_length
max_length = 4
それ以降j=min_length; j++; j<max_length

str+=word2[2]+word3[3]

これで行けるはず

yussakyussak

pythonに慣れてないのでjsっぽい書き方をしている

min_length = max_length=nのときはi=0;i++;i<nでstr+=word1[i]+word2[i]

yussakyussak
# ex1=>word1[0]word2[0]word1[1]word2[1]word1[2]word2[2]
        # ex2=>word1[0]word2[0]word1[1]word2[1]word2[2]word2[3]
        # ex3=>word1[0]word2[0]word1[1]word2[1]word1[2]word1[3]

        # TODO:word1 length取得する
        # TODO:word2 length取得する
        # TODO:word1length, word2lengthを比較し、小さい方をmin_length,大きい方をmax_lengthとする。同じ場合にはword1lengthに対して処理を実行するよう分岐
        # strを宣言
        # もし長さが同じならi=0,1,2,...,word1.lengthに対してstrにword1[i]+word2[i]を足していく

        # 違う場合i=0,1,...min_lengthに対してstrにword1[i]+word2[1]を足していく
        # その後、長い方のwordに対してj=min_length,...,max_engthに対してstrにword[j]+word[j]を足していく

        # 最後にstrをreturn
yussakyussak
class Solution:
    def mergeAlternately(self, word1: str, word2: str) -> str:
        w1_len=len(word1)
        w2_len=len(word2)

        if w1_len == w2_len:
            str=""
            for i in range(w1_len):
                str += word1[i]+word2[i]
            return str  

        if w1_len > w2_len:
            str=""
            for i in range(w2_len):
                str += word1[i]+word2[i]
            for j in range(w2_len,w1_len):
                str += word1[j]
            return str
        else:
            str=""
            for i in range(w1_len):
                str += word1[i]+word2[i]
            for j in range(w1_len,w2_len):
                str += word2[j]
            return str

行けた!

yussakyussak

解答見て改善する。あとclaudeには以下のように言われている

パフォーマンスの改善とリファクタリングのポイントは以下の通りです。
文字列の連結には、文字列の加算よりもリストを使用し、最後に join() メソッドで結合する方が効率的です。
条件分岐を簡略化し、コードの重複を減らすことができます。
変数名を分かりやすく改善することができます。

yussakyussak
i = 0
while i < len(word1) or i < len(word2):
...
i += 1

iがword1またはword2の長さ未満の間処理を続ける。両方とも以上になった時点で終了(片方が以上では止まらない。勘違いしてた)

if i < len(word1):
    result.append(word1[i])
if i < len(word2):
    result.append(word2[i])

で、whileの条件が片方だけfalseになっても処理を続けられるようwhile内で分岐しているのか

一個ずつwhileを書くこともできるがまとめられるのでまとめてる。で条件分岐で切り替えている

yussakyussak

で最後にappendしたものをjoinしてる
自分の答えは都度文字列を追加してるのをまとめてやるほうが早いんだな

yussakyussak

模範解答は理解できたけどなぜそのコードになったのかがわかってないので丸暗記になってしまい嫌だ
なので自分のコードを改善していったら模範解答に近づいた がいいんだろう?

yussakyussak

改善してる

配列作ってappendしてjoinするようにした

あと今はforで書いていて要素の長さに依存しており条件分岐が多くなってる
これはwhileを使えば減らせそう

yussakyussak

こうかければ良さそうというのを日本語で書いてくとスムーズだな

 while 条件:
    if 条件:
        result.append(word1[i])
    if 条件:
        result.append(word2[i])
yussakyussak

iを使って繰り返すにはfor or while
forだとrangeが必要だがそれだと条件が複雑になる、でもwhileだとそれよりシンプルに書ける

yussakyussak

whileの条件はifの条件両方がtrueのときに実行されればいいか、それなら i <len(word1) and i <len(word2) か?いやそれだと追加されない文字が出るので違う。じゃあ i <len(word1) or i <len(word2) か?これなら片方がfalseになっても続行できるのでOKか
という考えになるか

このスクラップは12日前にクローズされました