1

Google が提供している無料の Python クラス (興味がある場合はリンク)を使用していますが、演習の 1 つに行き詰まっています。

目標: 文字列を 2 つに分割することを検討してください。長さが偶数の場合、前半分と後ろ半分の長さは同じです。長さが奇数の場合、余分なイワナは前半に入ると言います。例: 'abcde'、前半は 'abc'、後半は 'de' です。2 つの文字列 a と b を指定すると、a-front + b-front + a-back + b-back の形式の文字列が返されます

これは私がこれまでに持っているものです:

def front_back(a, b):
    if len(a)%2 == 0 or len(b)%2 == 0:
        firstpart , secondpart = a[:len(a)/2] , a[len(a)/2:]
        thirdpart , fourthpart = b[:len(b)/2] , b[len(b)/2:]
    else:
        firstpart , secondpart = a[:len(a)+1/2] , a[len(a)+1/2:]
        thirdpart , fourthpart = b[:len(b)+1/2] , b[len(b)+1/2:]
    return firstpart+thirdpart+secondpart+fourthpart

テスト文字列は次のとおりです。

 test(front_back('abcd', 'xy'), 'abxcdy')
 test(front_back('abcde', 'xyz'), 'abcxydez')
 test(front_back('Kitten', 'Donut'), 'KitDontenut')

それぞれの 3 番目の文字列は、予想される文字列です。

私は何を間違っていますか?奇数の長さの文字列を説明できないことが問題であることはわかっていますが、ここ数日検索していて、オンラインで答えを見つけることができませんでした. 私はより効率的なソリューションにもオープンですが、将来の参考のために、特定のセットアップがうまくいかない理由を知りたいです。

ありがとう!

4

4 に答える 4

2

あなたの問題は、 a と b を別々のケースとして扱っていないことです。a の長さが 4 で b の長さが 5 の場合を考えてみましょう。

def front_back(a, b):
    if len(a)%2 == 0:
        firstpart , secondpart = a[:len(a)/2] , a[len(a)/2:]
    else:
        firstpart , secondpart = a[:len(a)+1/2] , a[len(a)+1/2:]

    if len(b)%2 == 0:
        thirdpart , fourthpart = b[:len(b)+1/2] , b[len(b)+1/2:]
    else
        thirdpart , fourthpart = b[:len(b)/2] , b[len(b)/2:]

    return firstpart+thirdpart+secondpart+fourthpart
于 2013-06-08T18:30:04.070 に答える
2

実装を分割関数とマージに分割する必要があります。そのようにテストする方が簡単です。また、分割の定義方法によって、最初の関数をかなり単純化できます。

文字列 s の長さが偶数の場合len(s)//2、整数除算は と同じ(len(s)+1)//2です。奇数の場合、len(s)//2は より 1 小さいです(len(s)+1)//2。最初の部分として長い文字列が必要なため、分割関数は次のように記述できます。

def splitter(s):
    mid = (len(s)+1)//2
    return s[:mid], s[mid:]

次に、マージのために:

def front_back(a,b):
    a_front, a_back = splitter(a)
    b_front, b_back = splitter(b)
    return "".join((a_front, b_front, a_back, b_back))
于 2013-06-08T18:47:59.077 に答える
1

コードを繰り返さないようにしてください。1 つの文字列を 1 回分割し、同じ規則に従って 2 番目の文字列を分割する場合は、小さな関数を記述してください。splitter()メイン関数内に呼び出される関数を入れましたfront_back()

#!/usr/bin/env python

def front_back(a, b):

  def splitter(s):
    l = len(s)
    if l%2 == 0:
      d = l/2
    else:
      d = (l/2) +1
    return (s[:d], s[d:])

  a1, a2 = splitter(a)
  b1, b2 = splitter(b)

  return a1 + b1 + a2 + b2

それを試してみてください...

于 2013-06-08T18:48:43.150 に答える
1

より簡単な方法:

def front_back(a, b):
    hlena, hlenb = (len(a) + 1)/2, (len(b) + 1)/2
    return a[:hlena] + b[:hlenb] + a[hlena:] + b[hlenb:]

if空の文字列のケースを処理する句は必要ありません。コード内のスライス計算の操作の順序が正しくありませんでした。

ヒント: 掘り下げてコーディングする前に、問題の簡潔な表現が得られるまで、REPL シェルで問題を試してみてください。初心者が抱える最大の課題の 1 つは、作成するコードが必要以上に大きくなり、理解とデバッグが難しくなることです。実行可能な最小のチャックから始めて、そこから構築します。

于 2013-06-08T18:53:57.590 に答える