繁体   English   中英

获取其值总计为给定数字的列表的索引

[英]Get the indices of a list whose value add up to the given number

我有一个值列表,并输入了一个数字。 该函数必须返回列表中的索引,其值加起来等于数字。 问题是列表包含重复的数字,并且返回的索引应该不相同。 这是我所拥有的,但是解决方案看起来并不干净。 有没有更好的办法?

finalList = []
def getIndices(number):
  values = [10,20,20,50,100,200,200,500,1000,2000,2000,5000]
  for i in range(len(values)):
    if values[i] == number:
      if i not in finalList:
        finalList.append(i)
      else:
        finalList.append(i-1)
      return values
    elif values[i] < number:
      continue
    else:
      number = number - values[i-1]
      if i-1 not in finalList:
        finalList.append(i-1)
      else:
        finalList.append(i-2)
      if number <= 0:
        break
      return getIndices(number)


result = getIndices(450)
print(result)

产量

[6, 5, 3]

如果我在追加之前没有检查列表,那么我会得到[6, 6, 3] 6,6,3 [6, 6, 3] ,这不是我想要的。

如果值列表已排序,则以下代码将执行您想要的操作。 这里的技巧是按照相反的顺序遍历列表。

但是请注意函数中的编辑和最后一个测试!

编辑:该问题被称为子集和问题 (请参阅Wikipedia ),并且是NP完全的。 应该马上认出来,我不好。 这基本上意味着没有简单有效的解决方案。 最简单的解决方案是尝试所有可能的组合,但是如果您的值列表很大,则只需花费很长时间即可完成。

def getIndices(number, values):
    '''Return a tuple (n, l) where l is a list of indices in 'values' and the
    following condition holds: n + sum(values[i] for i in l) == number.

    values -- sorted list of numbers
    number -- sum to search for

    >>> values=[10,20,20,50,100,200,200,500,1000,2000,2000,5000]
    >>> getIndices(18000, values)
    (6900, [11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
    >>> getIndices(450, values)
    (0, [6, 5, 3])
    >>> getIndices(15, values)
    (5, [0])
    >>> getIndices(10, values)
    (0, [0])
    >>> getIndices(5, values)
    (5, [])
    >>> getIndices(0, values)
    (0, [])

    This simplicist algorithm does not always find a solution with 'n' == 0,
    even if one exists. The following test fails, it returns (10, [2])
    instead.

    >>> getIndices(40, [20, 20, 30])
    (0, [0, 1])

    '''
    n = number
    l = []

    for i in range(len(values) - 1, -1, -1):
        if values[i] <= n:
            l.append(i)
            n -= values[i]

    assert(n + sum(values[i] for i in l) == number)
    return n, l


if __name__ == '__main__':
    import doctest
    doctest.testmod()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM