如何编写用于拆分数组偶数和奇数索引的递归函数?

时间:2016-01-04 14:31:10

标签: python arrays algorithm recursion

这是我的采访的问题。

编写一个执行以下操作的递归函数:

输入:长度为N的阵列A.N是偶数,N> = 2。

输出:重新排序的数组B.B的前半部分包含具有偶数索引的A元素。 B的后半部分包含具有奇数索引的A元素。约定:数组的第一个索引是0(因此它是偶数)。

Input 1: [4, 8, 12, 16]

对于此数组,索引和值如下:

Index: 0, 1,  2,  3
Value: 4, 8, 12, 16

因此,输出如下:

Expected output 1: [4, 12, 8, 16]

其他测试案例

Input 2: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Expected output 2: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]

TASK

使用您选择的编程语言编写递归函数(就好像您正在编写要在生产服务器上使用的实际代码)以解决上述问题 除了main函数之外,您还可以自由编写辅助函数(如果需要)

代码应该尽可能少(但它应该仍然清晰可读)

注意:您的递归功能必须显示'精神'递归函数(不仅仅是for循环的递归形式)

这是我的代码:

def slove(array, deep=0):
    '''para:
        array: list input.
    return: list.
    !!!Do not set value for deep!!!'''
    if len(array) > 2:
        if deep > 0:
            for i in xrange(0, len(array), 2):
                array[i], array[i + 1] = array[i + 1], array[i]
        left = array[0]
        right = array[-1]
        array = array[1:-1]
        array = slove(array, deep + 1)
        array.insert(0, left)
        array.append(right)
        return array
    else:
        array[0], array[-1] = array[-1], array[0]
        return array


if __name__ == '__main__':
    array = map(int, raw_input('Enter array with sep is space key: ').split(' '))
    # array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    print slove(array)

他说这是错误的,因为我在程序中使用循环。他是对的?那怎么解决呢?

4 个答案:

答案 0 :(得分:0)

为什么不直接使用切片?

lst = [11,12,13,14,15,16]
lst[0::2] + lst[1::2]

返回:

[11, 13, 15, 12, 14, 16]

答案 1 :(得分:0)

这个伪代码功能可能会有所帮助:

Let A[n] and B[n] be the 2 arrays where n is the size.

然后我们将调用以下方法rearrange(0,0)

rearrange(int i, int j) {
    b[j] = a[i];
    b[j+n/2] = a[i+1];
    if (j < n/2-1)
        rearrange(i+2,j+1);
}

在此方法中,i每次跳转2次,因此奇数项存储在输出数组的前半部分。对于下半场,j+n/2会保存偶数项目。

答案 2 :(得分:0)

这是一种(笨拙的)方式:

def even_odd_split(seq):
    """
    >>> even_odd_split([4, 8, 12, 16])
    [4, 12, 8, 16]
    >>> even_odd_split([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
    [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
    """
    assert(len(seq) % 2 == 0)
    assert(len(seq) > 1)

    def _split(seq):
        if len(seq) == 0: return [], []

        a, b = _split(seq[2:])
        return [seq[0]] + a, [seq[1]] + b
    a, b = _split(seq)
    return a + b

if __name__ == '__main__':
    import doctest
    doctest.testmod()

答案 3 :(得分:0)

我会这样解决:

def f(l):
    if len(l) == 1:
        # only one element left
        return l
    if len(l) % 2 == 0:
        # length is even
        return l[:1] + f(l[1:])
    else:
        # length is odd
        return f(l[1:]) + l[:1]

每次调用该函数都会从列表中删除一个元素,并将其放在结果列表的开头或末尾。

它不会产生给定的“预期”输出,因为列表的元素显示的顺序不同于它们在输入列表中出现的顺序,但它符合规范......而且,我认为它非常简单。