Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何通过使用python添加来获得目标_Python_Add_Itertools - Fatal编程技术网

如何通过使用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]*目标
对于元素