在python中尝试实现合并算法合并到已排序整数列表时出错?

在python中尝试实现合并算法合并到已排序整数列表时出错?,python,algorithm,merge,Python,Algorithm,Merge,我对算法和编程都是新手 作为合并算法的介绍,本章首先介绍了合并算法本身。它合并并排序由2个排序子数组组成的数组 我根据书中的描述在纸上做了伪代码: 资料来源:“算法简介” 第三版“托马斯·H·科门·查尔斯·E·莱瑟森·罗纳德·L·里维斯特·克利福德·斯坦” 由于我是在python3中实现它的,因此我不得不更改一些行,因为python中的索引从0开始,这与本书的伪代码示例不同 请记住,输入是一个数组,其中包含两个已排序的子数组,然后合并、排序并返回。我把指纹保存在我的密码里,所以你可以看到我的支

我对算法和编程都是新手

作为合并算法的介绍,本章首先介绍了合并算法本身。它合并并排序由2个排序子数组组成的数组

我根据书中的描述在纸上做了伪代码:

资料来源:“算法简介” 第三版“托马斯·H·科门·查尔斯·E·莱瑟森·罗纳德·L·里维斯特·克利福德·斯坦”

由于我是在
python3
中实现它的,因此我不得不更改一些行,因为python中的索引从0开始,这与本书的伪代码示例不同

请记住,输入是一个数组,其中包含两个已排序的子数组,然后合并、排序并返回。我把指纹保存在我的密码里,所以你可以看到我的支票

#!/anaconda3/bin/python3

import math
import argparse

# For now only MERGE slides ch 2 -- Im defining p q and r WITHIN the function
# But for MERGE_SORT p,q and r are defined as parameters!

def merge(ar):
    '''
    Takes as input an array. This array consists of 2 subarrays that ARE ALLREADY sorted 
    (small to large). When splitting the array into half, the left
    part will be longer by one if not divisible by 2. These subarrays will be
    called left and right. Each of the subarrays must already be sorted. Merge() then 
    merges these sorted arrays into one big sorted array. The sorted array is returned.
    '''
    print(ar)
    p=0 # for now defining always as 0
    if len(ar)%2==0:
        q=len(ar)//2-1 # because indexing starts from ZERO in py
    else:
        q=len(ar)//2 # left sub array will be 1 item longer 
    r=len(ar)-1 # again -1 because indexing starts from ZERO in py
    print('p', p, 'q', q, 'r', r)

    # lets see if n1 and n2 check out
    n_1 = q-p+1 # lenght of left subarray
    n_2 = r-q # lenght of right subarray
    print('n1 is: ', n_1)
    print('n2 is: ', n_2)
    left = [0]*(n_1+1) # initiating zero list of lenght n1
    right=[0]*(n_2+1)
    print(left, len(left))
    print(right, len(right))

    # filling left and right
    for i in range(n_1):# because last value will always be infinity
        left[i] = ar[p+i]
    for j in range(n_2):
        right[j] = ar[q+j+1]
        #print(ar[q+j+1])
        #print(right[j])
    # inserting infinity at last index for each subarray
    left[n_1]=math.inf
    right[n_2]=math.inf
    print(left)
    print(right)
    # merging: initiating indexes at 0
    i=0
    j=0
    print('p', p)
    print('r', r)
    for k in range(p,r):
        if left[i] <= right[j]:
            ar[k]=left[i]
            # increase i
            i += 1
        else:
            ar[k]=right[j]
            #increase j
            j += 1
    print(ar)
#############################################################################################################################
# Adding parser
#############################################################################################################################
parser = argparse.ArgumentParser(description='MERGE algorithm from ch 2')
parser.add_argument('-a', '--array', type=str, metavar='', required=True, help='One List of integers composed of 2 sorted halves. Sorting must start from smallest to largest for each of the halves.')
args = parser.parse_args()
args_list_st=args.array.split(',') # list of strings
args_list_int=[]
for i in args_list_st:
    args_list_int.append(int(i))
    
if __name__ == "__main__":
    merge(args_list_int)

对于任何大于6的数组,都不会发生这种情况

$ ./2.merge.py -a=2,4,5,7,1,2,3,8
[2, 4, 5, 7, 1, 2, 3, 8]
p 0 q 3 r 7
n1 is:  4
n2 is:  4
[0, 0, 0, 0, 0] 5
[0, 0, 0, 0, 0] 5
[2, 4, 5, 7, inf]
[1, 2, 3, 8, inf]
p 0
r 7
[1, 2, 2, 3, 4, 5, 7, 8]
我把它给班上的一位同事看了,但没有成功。我已经用纸片上的数字手动完成了,但没有成功。我希望有人能发现我愚蠢的错误,因为我完全被卡住了


感谢因为
r
arr
中最后一个值的索引,您需要向其中添加一个值,以形成一个范围,该范围还包括最终索引:

for k in range(p, r + 1):
#                 ^^^^^

请注意,如果使用列表切片,代码可能会大大减少。

兄弟,您在这一行中犯了一个很小的错误
范围内的k(p,r):
在这里,循环从p运行到r-1,最后一个索引即r不会被迭代。 所以你必须使用
范围内的k(p,r+1):

在第二个测试用例中
a=[2,4,5,7,1,2,3,8]
即使使用错误的代码,您也会得到正确的输出,因为您正在覆盖数组
ar
中的值,并且您当前的代码能够对数组进行排序,直到索引
r-1
,索引r中的数字将与执行合并函数之前的数字相同,即8

尝试使用此测试用例:
[2,4,5,8,1,2,3,7]

您的输出将是
[1,2,2,3,4,5,7,7]


希望这有帮助

我仍然很困惑,为什么我的糟糕版本仍然返回正确的结果,并且任何数字都高于6。没关系,我想它只是突然在我的大脑中出现了。因为arr在我排序和合并时被修改,所以任何大于6的数字都已经在最后一个位置(应该在哪里)。因此,它没有受到干涉。
for k in range(p, r + 1):
#                 ^^^^^