假设我有两个(或更多,但是这个例子,两个会做)不同大小的列表,我想迭代每个。我不想同时遍历每个 ,这意味着虽然我将同时访问这两个,但我可能不希望同时逐步移动它们。
例如,假设我要合并两个不同长度的排序数组。让我们说我有一个天真的解决方案,我想实现(我知道有更好的解决方案),就像这样:
a
和b
中的第一个元素。如果a[i=0] < b[j=0]
,请在列表a[i]
中插入c
。然后,增加i - > I + 1。现在,在最后,你应该有一个排序数组,这是合并这两个数组的结果。
我遇到的问题是如何我应该以漂亮的方式迭代这些数组。我的(while?for?)循环的条件应该是什么?如何在没有很多if语句检查边界和其他内容的情况下保持我的代码简洁?在设计这些类型的算法时,我一直难以提出“看起来不错”或效率最高的最佳策略/实现。
答案 0 :(得分:1)
漂亮是什么意思? 有两种方法可以做到:
以下是步骤:
i=0
,j=0
,列表a
和b
的索引。a
或b
的结尾。如果是,则只输出较长列表中的其余元素,然后转到步骤5(退出无限循环)。此处有三项检查:a[i]<b[j]
,a[i]==b[j]
,a[i]>b[j]
:
3.1。 a[i]<b[j]
。循环时这是真的并且未到达a
的结尾。在此循环中输出a[i]
并增加i
。
3.2。 a[i]=b[j]
。在此情况下循环,并且未达到a
或b
的结尾。在此循环中输出a[i]
和b[j]
并增加i
和j
。
3.3与3.1相同,但b[j]
。
转到第2步(无限循环)。
完成!
答案 1 :(得分:1)
为了便于说明,假设有四个列表 - 在多阶段合并排序的合并阶段可能n = 4。将索引收集到数组inx
中。从主列表data
引用您的列表。如果可以的话,从最后工作;这可能会将列表末端测试简化为对索引的简单“真实”测试。
data = [list1, list2, list3, list4]
idx = [lst.length() for lst in data]
candidates = [data[idx[i]]
for i in range(0, data.length())]
// Identify the next item to use
while (any(candidates is not NaN)) {
candidates = [if idx[i] then data[idx[i]]
else NaN
for i in range(0, data.length())]
// determine which list *i* holds the next element
elem = candidates[i]
idx[i] -= 1
// process elem
candidates = [if idx[i] then data[idx[i]]
else NaN
for i in range(0, data.length())]
}
这需要每个循环(在形成候选列表时)对每个索引符号进行一次检查,并对循环结束的元素进行NaN检查。缓存和部分结果可以最小化这一点,具体取决于您的实现语言中可用的习语。