我已经在Python中创建了一个合并排序程序,它运行得很好但是我已经修改它来计算所涉及的反转次数,现在它给了我一个错误:
这是我的代码:
def merge_list(left,right,c):
result=[]
i,j=0,0
while i < len(left) and j < len(right):
if left[i] < right[j]:
result.append(left[i])
print "Left result",result
i=i+1
elif left[i] > right[j]:
result.append(right[j])
print "Right result",result
j=j+1
if right[j] < left[i] and i<j:
c=c+1
result=result+left[i:]
result=result+right[j:]
print "Inversions: ",c
return result,c
def sort_and_count(lis,count):
if len(lis)<2:
return lis
middle=len(lis) / 2
left,c1=sort_and_count(lis[:middle],count)
print "left",left
right,c2=sort_and_count(lis[middle:],count)
print "right",right
m,c=merge_list(left,right,count)
c=c+c1+c2
return m,c
if __name__=="__main__":
print "Enter 6 elements: "
i=0;lis=[];merge_lis=[];inv=0
while i<=5:
x=int(raw_input())
lis.append(x)
i=i+1
count=0
merge_lis,inv=sort_and_count(lis,count)
print "Sorted list is: ",merge_lis,inv
我的追溯:
Traceback (most recent call last):
File "Sort_and_count.py", line 53, in <module>
merge_lis,inv=sort_and_count(lis,count)
File "Sort_and_count.py", line 31, in sort_and_count
left,c1=sort_and_count(lis[:middle],count)
File "Sort_and_count.py", line 31, in sort_and_count
left,c1=sort_and_count(lis[:middle],count)
ValueError: need more than 1 value to unpack
这种方法我哪里错了?
答案 0 :(得分:3)
实际上,您已经实现了错误的算法来计算反转次数。
1)在函数merge_list
而不是:
elif left[i] > right[j]:
result.append(right[j])
print "Right result",result
j=j+1
if right[j] < left[i] and i<j:
c=c+1
你应该使用这段代码:
elif right[j] < left[i]:
result.append(right[j])
j += 1
inv_count += (len(left)-i)
2)函数merge_list
不需要变量c
作为输入。
3)函数sort_and_count
不需要变量count
作为输入。
试试这段代码:
def merge_list(left,right):
result = list()
i,j = 0,0
inv_count = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
result.append(left[i])
i += 1
elif right[j] < left[i]:
result.append(right[j])
j += 1
inv_count += (len(left)-i)
result += left[i:]
result += right[j:]
return result,inv_count
def sort_and_count(array):
if len(array) < 2:
return array, 0
middle = len(array) / 2
left,inv_left = sort_and_count(array[:middle])
right,inv_right = sort_and_count(array[middle:])
merged, count = merge_list(left,right)
count += (inv_left + inv_right)
return merged, count
if __name__=="__main__":
array = [2,3,1,4,5]
merge_array,inversions = sort_and_count(array)
print 'Start with array: %s;\nSorted array: %s;\nInversions: %s.'%(array,merge_array,inversions)
答案 1 :(得分:1)
错误消息告诉您sort_and_count
仅返回单个值。函数中只有两个返回值,因此罪魁祸首就是这个:
if len(lis)<2:
return lis
答案 2 :(得分:1)
这一行:
return lis
这是一个问题,因为你期望sort_and_count
返回一个包含两个值的元组,所以当它只返回一个值时,你会遇到像left,c1=sort_and_count(lis[:middle],count)
这样的行解包的问题。该行应返回两个值,如该方法的最后一行:
return m,c
答案 3 :(得分:1)
而不是
return lis
DO
return lis, count
答案 4 :(得分:1)
嗯,你正在返回一个值,他预计会有两个值。
看看
def sort_and_count(lis,count):
if len(lis) < 2:
return lis
middle = len(lis) / 2
left, c1 = sort_and_count(lis[:middle],count)
# etc
如果你调用sort_and_count([1],count),那么len(lis)将是&lt; 2,它将返回单元素列表,但不会返回计数,这在下面的调用中是预期的。
只需返回c1的值,如
return lis, count # do your things with count