1

我正在学习谷歌提供的免费 Python 课程(如果有兴趣,请链接),我被困在其中一个练习上。

目标:考虑将字符串分成两半。如果长度是偶数,则前半部分和后半部分长度相同。如果长度是奇数,我们会说额外的字符在前半部分。例如'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')

每个中的第三个字符串是预期的字符串。

我究竟做错了什么?我知道这个问题无法解释奇数长度的字符串,但我已经搜索了几天,但我没有运气在网上找到答案。我也对更有效的解决方案持开放态度,但我想知道为什么我的特定设置不起作用,以供将来参考。

谢谢!

4

4 回答 4

2

您的问题是您没有将 a 和 b 视为单独的案例。考虑 a 长度为 4 且 b 长度为 5 的情况。在这种情况下,您总是会选择第一个分支,这会错误地处理 b。

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

尽量避免重复代码.. 如果您将一个字符串拆分一次,然后按照相同的规则拆分第二个字符串,只需编写一个小函数即可!我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 shell 中解决问题,直到您对问题有一个简洁的表示。初学者面临的最大挑战之一是他们创建的代码比需要的大得多,这使得理解和调试变得更加困难。从最小的可用卡盘开始,然后从那里开始构建。

于 2013-06-08T18:53:57.590 回答