如何通过使用python添加来获得目标
我有一张名单和一个目标号码如何通过使用python添加来获得目标,python,add,itertools,Python,Add,Itertools,我有一张名单和一个目标号码 我需要打印达到目标的方法的数量 方法的数量如下 1+1+1+1+1=5 1+1+1+2=5 1+2+2=5 1+1+3=5 2+3=5 输出5路 def countways(l, target ): if (target == 0): return 0 else: pass if __name__ == "__main__": l = [1,2,3], target
- 我需要打印达到目标的方法的数量
- 1+1+1+1+1=5
- 1+1+1+2=5
- 1+2+2=5
- 1+1+3=5
- 2+3=5
5路
def countways(l, target ):
if (target == 0):
return 0
else:
pass
if __name__ == "__main__":
l = [1,2,3],
target = 5
countways(l, target )
我们可以使用本机python或itertools来实现吗?下面的方法很有效
计数从指定列表的元素计算目标的方法
def计数方式(A、n、目标):
#基本情况:如果找到目标
如果目标==0:
返回1
#基本情况:没有留下任何元素
如果n<0:
返回0
# 1. 忽略当前元素
排除=计数方式(A,n-1,目标)
# 2. 考虑当前元素
# 2.1. 从目标中减去当前元素
# 2.2. 将当前元素添加到目标
include=countWays(A,n-1,target-A[n])+countWays(A,n-1,target+A[n])
#返回总计数
返回排除+包括
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
#输入列表和目标编号
A=[5,3,-6,2]
目标=6
打印(计数方式(A,透镜(A)-1,目标),“方式”)
下面的方法有效
计数从指定列表的元素计算目标的方法
def计数方式(A、n、目标):
#基本情况:如果找到目标
如果目标==0:
返回1
#基本情况:没有留下任何元素
如果n<0:
返回0
# 1. 忽略当前元素
排除=计数方式(A,n-1,目标)
# 2. 考虑当前元素
# 2.1. 从目标中减去当前元素
# 2.2. 将当前元素添加到目标
include=countWays(A,n-1,target-A[n])+countWays(A,n-1,target+A[n])
#返回总计数
返回排除+包括
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
#输入列表和目标编号
A=[5,3,-6,2]
目标=6
打印(计数方式(A,透镜(A)-1,目标),“方式”)
您可以使用以下方法:
输出:
5
(2, 3)
(1, 1, 3)
(1, 2, 2)
(1, 1, 1, 2)
(1, 1, 1, 1, 1)
解释 该方法的docstring如下所示: 返回输入iterable中元素的r长度子序列,允许单个元素重复多次 因此,它与方法类似,希望
itertools.compositions\u with\u replacement()
方法允许重复元素
如果要可视化不同的解决方案:
from itertools import combinations_with_replacement as cwr
def countways(l, target):
for i in range(target):
for j in cwr(l, i + 1):
if sum(j) == target:
print(j)
countways([1, 2, 3], 5)
输出:
5
(2, 3)
(1, 1, 3)
(1, 2, 2)
(1, 1, 1, 2)
(1, 1, 1, 1, 1)
注意:正如@He3lixxx(+1)所指出的,对于大输入来说,这可能非常慢。您可以通过过滤掉
l
中大于target
的数字,并将范围(target)
中的target
除以max(l)
和min(l)
来提高效率,如下所示:
def countways(l, target):
l = [i for i in l if i <= target]
return len([1 for i in range(target // max(l) - 1,
target // min(l)) for j in cwr(l, i + 1) if sum(j) == target])
def计数方式(l,目标):
l=[i代表l中的i如果i您可以使用以下方法:
输出:
5
(2, 3)
(1, 1, 3)
(1, 2, 2)
(1, 1, 1, 2)
(1, 1, 1, 1, 1)
解释
该方法的docstring如下所示:
返回输入iterable中元素的r长度子序列,允许单个元素重复多次
因此,它与方法类似,希望itertools.compositions\u with\u replacement()
方法允许重复元素
如果要可视化不同的解决方案:
from itertools import combinations_with_replacement as cwr
def countways(l, target):
for i in range(target):
for j in cwr(l, i + 1):
if sum(j) == target:
print(j)
countways([1, 2, 3], 5)
输出:
5
(2, 3)
(1, 1, 3)
(1, 2, 2)
(1, 1, 1, 2)
(1, 1, 1, 1, 1)
注意:正如@He3lixxx(+1)所指出的,对于大输入,这可能非常慢。您可以通过过滤出l
中大于target
的数字,并将范围(target)
中的目标
除以max(l)
和min(l)
来提高效率,如下:
def countways(l, target):
l = [i for i in l if i <= target]
return len([1 for i in range(target // max(l) - 1,
target // min(l)) for j in cwr(l, i + 1) if sum(j) == target])
def计数方式(l,目标):
l=[i表示l中的i,如果i我将假设所有数字都是正数
您可以使用itertools检查所有带有替换的组合,正如Ann所建议的那样,但是对于大输入来说,它会变得不必要的慢,因为有成倍多的组合
朴素递归方法
这个版本使用了Nevetha描述的递归方法,它允许在没有匹配项的分支中提前返回,但是应该通过替换来完成
与其他结果一样:打印实际的总和是相当容易的。我们只需添加一个可选的第三个参数,该参数给出了目前为止的总和,并在target==0
的情况下打印它
def计数方式(元素、目标):
如果目标<0:
返回0
如果目标==0:
返回1
总数=0
对于索引,枚举中的元素(元素):
总计+=计数方式(元素[索引:],目标-元素)
返回总数
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
打印(计数方式([1,2,3,5))
打印(计数方式([5,31,32,33,34,35,36,37,38,39,40,30))
打印(计数方式([2,3,5,7,11,13,17,19,23,29,31,37,40))
打印(计数方式([1,2,3,4,5,200))
DP算法
如您所见,对于200的目标,这已经需要相当长的时间来执行。这是因为在递归结束时,我们总是只在结果中添加一个。这可以通过使用动态编程来改进——或者通过简单地添加缓存(示例代码,当然全局变量不应该在任何实际程序中使用):
cache={}
def计数方式(元素、目标):
全局缓存
如果目标<0:
返回0
如果目标==0:
返回1
cache_key=(元组(元素),目标)
如果在缓存中缓存\u键:
返回缓存[cache\u key]
总数=0
对于索引,枚举中的元素(元素):
总计+=计数方式(元素[索引:],目标-元素)
缓存[缓存密钥]=总计
返回总数
或者直接构建dp阵列,如前所述:
def计数方式(元素、目标):
dp=[1]+[0]*目标
对于元素