Algorithm 迭代不同大小的多个列表的最佳方法是什么?

Algorithm 迭代不同大小的多个列表的最佳方法是什么?,algorithm,Algorithm,假设我有两个(或更多,但在本例中,两个就可以了)大小不同的列表,我希望遍历每个列表。我不想同时遍历每一个,这意味着虽然我将同时访问这两个,但我可能不想同时递增地遍历这两个 例如,假设我想合并两个长度不同的排序数组。假设我有一个我想要实现的简单解决方案(我知道有更好的解决方案),它是这样的: 检查列表a和b中的第一个元素。如果a[i=0]i+1 如果不是,那么就为j 现在,在最后,您应该有一个排序数组,它是合并这两个数组的结果 我遇到的问题是,我应该如何以一种非常好的方式迭代这些数组。我的(whi

假设我有两个(或更多,但在本例中,两个就可以了)大小不同的列表,我希望遍历每个列表。我不想同时遍历每一个,这意味着虽然我将同时访问这两个,但我可能不想同时递增地遍历这两个

例如,假设我想合并两个长度不同的排序数组。假设我有一个我想要实现的简单解决方案(我知道有更好的解决方案),它是这样的:

  • 检查列表
    a
    b
    中的第一个元素。如果
    a[i=0]
    ,则在列表
    c
    中插入
    a[i]
    。然后,增加i->i+1
  • 如果不是,那么就为j
  • 现在,在最后,您应该有一个排序数组,它是合并这两个数组的结果

    我遇到的问题是,我应该如何以一种非常好的方式迭代这些数组。我的(while?for?)循环的条件应该是什么?我如何保持我的代码简洁,而不使用很多检查边界和其他东西的if语句?在设计这些类型的算法时,我通常很难想出“看起来不错”或有效的最佳策略/实现。

    什么是“漂亮”? 有两种方法可以做到这一点:

    • 调用一个虚构的函数,它正好做到这一点。这看起来很“漂亮”
    • 编写您自己的代码,这与这个虚构函数在内部所做的相同
    以下是步骤:

  • 设置
    i=0
    j=0
    ,列表的索引
    a
    b
  • 检查是否到达
    a
    b
    的末尾。如果是,则只输出较长列表中的其余元素并转到步骤5(退出无限循环)
  • 这里有三个检查:
    a[i]b[j]

    3.1<代码>a[i]美丽是什么意思? 有两种方法可以做到这一点:

    • 调用一个虚构的函数,它正好做到这一点。这看起来很“漂亮”
    • 编写您自己的代码,这与这个虚构函数在内部所做的相同
    以下是步骤:

  • 设置
    i=0
    j=0
    ,列表的索引
    a
    b
  • 检查是否到达
    a
    b
    的末尾。如果是,则只输出较长列表中的其余元素并转到步骤5(退出无限循环)
  • 这里有三个检查:
    a[i]b[j]


    3.1<代码>a[i]为便于说明,假设有四个列表——在多阶段合并排序的合并阶段,n=4。将索引收集到一个数组中,
    inx
    。从主列表中引用列表,
    数据
    。如果可以的话,从头开始工作;这可以将列表结束测试简化为索引的简单“真实”测试

    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检查。缓存和部分结果可以最大限度地减少这种情况,具体取决于实现语言中可用的习惯用法。

    为了说明起见,假设有四个列表——在多阶段合并排序的合并阶段,n=4。将索引收集到一个数组中,
    inx
    。从主列表中引用列表,
    数据
    。如果可以的话,从头开始工作;这可以将列表结束测试简化为索引的简单“真实”测试

    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检查。缓存和部分结果可以最小化这一点,这取决于实现语言中可用的习惯用法。

    如何将所有列表放入优先级队列中,并将它们视为要消耗的资源?因此,每次您通过弹出队列头来使用列表时。获得列表后,可以增加其索引,并将列表重新插入优先级队列。队列是按每个列表的当前元素值排序的。@MincongHuang我知道这是一个很好的也是最好的实现。注意我的问题——我不是在问合并两个列表的最佳方法是什么。我只是以合并两个列表的简单实现为例来更好地说明我遇到的一个更大的问题。
    merge
    函数的无数实现可供检查。哪些部分对你不起作用?@Prune我不太关注合并。同样,我使用两个列表的合并作为一个例子,来说明我在决定在两个不同大小的列表之间迭代的最佳方式时遇到的一个问题。具体来说,我发现自己使用了很多if语句(4-6)来测试边界、比较和其他东西。我在想,也许有一种更干净的方法来编写if语句或检查所有这些条件,而不会让代码看起来有那么多ifstatements@JohnLexus在这个示例问题中,您可以看看我对python迭代器的使用:在迭代器决定下一个应该生成的值之前,变量已经更改。在Python搜索生成器中,收益率、迭代器、迭代工具将所有的列表放入优先级队列中,并将它们视为消耗的资源?因此,每次您通过弹出队列头来使用列表时。获得列表后,可以增加其索引,并将列表重新插入优先级队列。队列是按每个列表的当前元素值排序的。@MincongHuang我知道这是一个很好的也是最好的实现。注意我的问题——我不是在问合并两个列表的最佳方法是什么。我只是以合并两个列表的简单实现为例,来更好地说明我面临的一个更大的问题