【问题标题】:Is there a better way of copying elements of an array without knowing the length of the new array?有没有更好的方法在不知道新数组长度的情况下复制数组元素?
【发布时间】:2021-06-02 11:10:56
【问题描述】:

假设我有一个包含 8 个元素的数组:old_array = [6, 3, 0, 12, 14, 2, 10, 5],我从最后一个元素 old_array[7]=5 开始。我想使用新元素作为我想从old_array 复制到new_array 的下一个元素的索引。 结果是new_array = [0,2,5]。 下面是一些伪代码:

old_array = [6, 3, 0, 12, 14, 2, 10, 5]
i=7
len=0
while i>0:
    len+=1
    i=old_array[i]

i=7
while i>0:
    new_array[len]=old_array[i]
    len-=1
    i=old_array[i]

这种方法确实有效,但是由于它使用重复的代码,它似乎效率不高;一个循环获取新数组的长度,另一个循环复制数组。 我的问题是有更好的方法吗?

编辑: 我期待一些伪代码比我当前的代码做得更好。 请注意,数组可以是任意的,除非最终会有一个 0 元素,并且有一种方法可以从最后一个元素获取它。我们也知道旧数组中的最后一个索引。 首选语言是 Python,但我也可以使用其他语言。

如果这个问题之前已经回答过或者可以改进,请指出我。谢谢。

【问题讨论】:

  • 对于不同的编程语言,答案会有所不同。您使用什么语言?
  • 这里已经回答了 -> stackoverflow.com/questions/4108313/…
  • @AndrewMerrill 我正在使用 Python。
  • @xx4g,这不是我想要的,那么你将如何将该数组复制到新数组?在 C 中执行 sizeof(array)/sizeof(array[0]) 只是给了我一个数组的大小,但我已经知道了。
  • 我投了“需要关注”的票,因为不同的语言对“数组”是什么有不同的想法。如果您想要 Python 的答案,请询问 Python,如果您好奇,请为 C 创建另一个问题(显然,请先搜索,等等)。Stack Overflow 不是一个关于如何进行开放式讨论的好地方 所有编程语言做任何事情。

标签: python arrays loops optimization


【解决方案1】:

您可以简单地从一个空列表开始,然后逐个添加项目:

indices = [6, 3, 0, 12, 14, 2, 10, 5]
start = -1
result = []
index = start
while index != 0:
    index = indices[index]
    result.append(index)
result

返回[5, 2, 0]

请注意,与您想要的输出相比,列表是颠倒的,因此您可以简单地颠倒它:

result[::-1]
# [0, 2, 5]

或使用deque 来添加值。

您似乎担心使用多个循环。如果您使用多个,这确实不是问题,而且您可能不会注意到任何性能差异。

您应该担心的是,如果索引超出范围(例如[3, 4, 5])或生成可能陷入无限循环(例如[0, 1]),您的列表没有正确定义。

据我所知,如果新列表定义正确,则它不能大于原始列表,因此如果您想使用静态长度,则可以使用相同的长度。

【讨论】:

  • 您好,感谢您的回复,这与我正在寻找的内容一致。你将如何使用不支持 array.append 的语言来做到这一点?你需要建立一个队列吗?
  • python也允许你做result[::-1],但是你需要做一个循环来用另一种语言反转它吗?
  • @LogicThinker12:我编辑了我的答案。使用两个循环而不是 1 个(甚至 100 个)确实不应该有太大的区别。不过,您的定义可能存在更大的问题。
【解决方案2】:

没有可以做到这一点的本机函数,但您可以在列表理解中使用一些技巧:

old = [6, 3, 0, 12, 14, 2, 10, 5]

new = [i.extend(old[i[0]:][:i[0]>0]) or i.pop(0) for i in [old[-1:]]
       for _ in old if i][::-1]

print(new)
[0, 2, 5]

这使用一个内部列表 (i) 来保存要放置在数组中的值。每次迭代都会将下一个值添加到i 列表中,并将其第一个值用作输出。下一个值取自 old 列表中 i 中指定位置的位置,前提是该位置 > 0。这就是 i.extend(old[i[0]:][:i[0]>0]) 所做的。鉴于append() 总是返回None,实际输出值也来自or i.pop(0),这也从i 中删除了值。当i 为空时,不再输出任何值。 for _ in old 部分确保我们将在复制所有元素的情况下执行所需的多次操作。

虽然 reduce() 函数被许多 Python 用户所反对,但它可以用于此:

from functools import reduce

new = reduce(lambda a,_:([old[a[0]]] + a) if a[0] else a,old[:-1],old[-1:])

print(new)
[0, 2, 5]

如果你打算使用循环来做,它可以简单地表示为:

new = old[-1:]
while new[0]:new.insert(0,old[new[0]])

print(new)
[0, 2, 5]

【讨论】:

  • 感谢您的回复,这是一种更短的方法。 Python允许你做result[::-1],但是你需要做一个循环来用另一种不支持这个特性的语言(比如C)来反转它吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-16
  • 1970-01-01
  • 1970-01-01
  • 2021-11-24
  • 2019-04-04
  • 2019-10-05
相关资源
最近更新 更多