python 递归程序中对象的浅拷贝与深拷贝

参考这个博客最长公共子序列(LCS)问题,写出了C++版的找出所有最大公共子序列的代码,然后我需要将这个代码用python实现一个,按照C++的逻辑,写出来后,但是最终的结果死活不正确,最后发现问题在于:递归过程中,递归变量在python中仅有一份,递归分支不能很好的保持过程中的状态量,需要对象的深拷贝。

#coding=utf8
#python3.5

import copy

MAX=10
len1=0
len2=0
# tag=[[0]*MAX]*MAX #这样得到的是浅拷贝:http://www.cnblogs.com/alibai/p/4027324.html
tag=[[0]*MAX for var in range(0,MAX)]
word_list1=[]
word_list2=[]
result=[]

def lcs_word(str1,str2):
	global len1,len2,word_list1,word_list2,tag
	word_list1=[var for var in str1.strip().split(" ") if var]
	word_list2=[var for var in str2.strip().split(" ") if var]
	if len(word_list1)>MAX-1:
		word_list1=word_list1[:MAX-1]
	if len(word_list2)>MAX-1:
		word_list2=word_list2[:MAX-1]
	len1=len(word_list1)
	len2=len(word_list2)
	for i in range(1,len1+1):
		for j in range(1,len2+1):
			if word_list1[i-1] == word_list2[j-1]:
				tag[i][j]=tag[i-1][j-1]+1
			else:
				tag[i][j]=max(tag[i-1][j],tag[i][j-1])

def output_all(clen1,clen2,cresult):
	global result
	if clen1==0 or clen2==0:
		# print(cresult[-1][::-1])
		result=cresult
		cresult.append([])
		return 
	if word_list1[clen1-1]==word_list2[clen2-1]:
		cresult[-1].append(word_list1[clen1-1])
		output_all(clen1-1,clen2-1,cresult)
	else:
		if tag[clen1-1][clen2]>tag[clen1][clen2-1]:
			output_all(clen1-1,clen2,cresult)
		elif tag[clen1-1][clen2]<tag[clen1][clen2-1]:
			output_all(clen1,clen2-1,cresult)
		else:
			# output_all(clen1-1,clen2,cresult)
			# output_all(clen1,clen2-1,cresult) #全局空间只有一份cresult,所以这样写不行,需要拷贝出来一个副本!
			#用上述的代码,输出的结果为:[['A', 'B', 'C', 'B'], ['B', 'A', 'C', 'B'], ['D', 'B'], []]
			temp_cresult=copy.deepcopy(cresult[-1]) #深拷贝,保存最后一个元素
			output_all(clen1-1,clen2,cresult)
			cresult[-1]=temp_cresult
			output_all(clen1,clen2-1,cresult)
			#真正需要的结果为:[['A', 'B', 'C', 'B'], ['B', 'A', 'C', 'B'], ['B', 'A', 'D', 'B'], []]

lcs_word("A B C B D A B","B D C A B A")
# print(len1,len2)
# [print(var[:len2+1]) for var in tag[:len1+1]]
# print(word_list1)
# print(word_list2)
# print("test")
output_all(len1,len2,[[]])
print(result[:-1])

还有两个问题:

1. 需要去重。

2. 输出函数的最初搜索点并不一定必须是tag[clen1][clen2],可以优化一下。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值