以之字形方式连接字符串列表的算法
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 新题