以之字形方式连接字符串列表的算法

Posted

技术标签:

【中文标题】以之字形方式连接字符串列表的算法【英文标题】:Algorithm to concatenate a list of strings in zig-zag fashion 【发布时间】:2020-04-27 07:10:51 【问题描述】:

我有以下问题:从字符串列表中,我必须从所有字符串中取第一个字母,之后(从后到前),我必须取第二个字母,在第三个字母之后从前面到结束等等。

示例输入:

['abcd', 'efgh', 'ijkl', 'mnop']

输出应该是:

'aeimnjfbcgkoplhd'

到目前为止,第一个“for”附加到数组中:aeim 和 cgko 第二个“for”附加到数组:njfb 和 plhd。反正顺序不好,我需要aeim + njfb + cgko + plhd

array = []
if len(list_of_strings[0]) % 2 == 0: # if we have strings with even number of letters
    for j in range(len(list_of_strings[0]/2)): # range(2) in our example
        for i in range(len(list_of_strings)): # range(4) in our example
            array.append(list_of_strings[i][j*2])

    for j in range(1, len(list_of_strings[0]), 2): # range(1, 4, 2) in our example
        for i in range(len(list_of_strings) - 1, -1, -1): # range(3, -1, -1) in our example
            array.append(list_of_strings[i][j])

请帮忙。

谢谢

【问题讨论】:

【参考方案1】:

您可以使用"unzip" (i.e. zip(*a)) 和str.join 使用简单的单行:

a = ['abcd', 'efgh', 'ijkl', 'mnop']
b = ''.join(''.join(t[::1-2*(i%2)]) for i, t in enumerate(zip(*a)))
assert b == 'aeimnjfbcgkoplhd'

join 可以将generator expression 作为参数,在这种情况下生成器表达式是

''.join(t[::1-2*(i%2)]) for i, t in enumerate(zip(*a))

表达式

zip(*a)

解压缩a 中的字符串,即它返回一个生成器,该生成器生成包含每个字符串的所有第一个字母、所有第二个字母等的元组。

索引

t[::1-2*(i%2)]

确保我们在每第二次迭代时反转元组的顺序。


编辑

我对我的单线与@cs95's answer 进行了基准测试,两者的性能在误差范围内是相同的。我认为在“真实代码”中,我更喜欢他的解决方案,因为它更清晰。

【讨论】:

【参考方案2】:

将字符视为二维数组中的元素:

a b c d
e f g h
i j k l
m n o p

我们想在奇数列上向下,然后在偶数列上向上,所以我们这样做:

chars = []
for i in range(len(l[0])):
    for w in l[::1 if i  % 2 == 0 else -1]:  
        chars.append(w[i])
print(''.join(chars))
# aeimnjfbcgkoplhd

l[::1 if i % 2 == 0 else -1] 将反转偶数列的列表,因此我们从末尾挑选字符。这是直观但丑陋的,因为对列表进行切片会创建一个浅拷贝。我们可以做一些更聪明的事情,通过使用 mod 来确定是否反向迭代:

chars = []
for i in range(len(l[0])):
    for j in range(len(l)) if i % 2 == 0 else reversed(range(len(l))):
        chars.append(l[j][i])
print(''.join(chars))
# aeimnjfbcgkoplhd

【讨论】:

非常感谢您的解决方案以及我应该如何思考的提示! @alex_mucenic 辛苦了,好问题,谢谢。 @alex_mucenic PS 我添加了第二个解决方案,展示了如何为内部循环切换迭代方向pythonically,PTAL @cs95 至少对于给定的(短)输入,“更聪明”的解决方案实际上比第一个解决方案慢很多(在我的机器上是 2.68µs 而不是 1.93µs)。只创建一次reversed(range(len(l))) 可能更快。 @cs95 range(len(l)-1, -1, -1) 也比反转范围更快。

以上是关于以之字形方式连接字符串列表的算法的主要内容,如果未能解决你的问题,请参考以下文章

如何以之字形顺序遍历二维数组

在二维数组中以之字形顺序打印数字

华为OD机试 2023最新 箱子之字形摆放(C++ 100%)

华为机试真题 Java 实现箱子之字形摆放2022.11 Q4 新题

华为机试真题 Python 实现箱子之字形摆放2022.11 Q4 新题

华为机试真题 C++ 实现箱子之字形摆放2022.11 Q4 新题