考虑以下情况:
items = [
{
id: 1
attributes: [
{ key: a, value: 2 }
{ key: b, value: 3 }
],
requirements: null
}
{
id: 2
attributes: [
{ key: b, value: 2 }
],
requirements: a > 2
}
{
id: 3
attributes: [
{ key: a, value: 1 }
{ key: c, value: 1 }
],
requirements: a > 1 and b > 2
}
{
id: 4
attributes: [
{ key: a, value: 2 }
{ key: d, value: 7 }
],
requirements: b > 5 and h < 10
}
]
将各种attributes
加在一起(总和)的预期结果是:
result = [
{ key: a, value: 3 }
{ key: b, value: 5 }
{ key: c, value: 1 }
]
正如您所看到的,列表中的对象之间存在依赖关系(requirements
)。特别是,从计算中丢弃具有id: 4
(系列的最后一个)的对象,因为从不检查条件b > 5 and h < 10
。相反,最初被丢弃的id: 2
对象由于具有id: 3
的对象(通过向属性{{1}添加1)而成为计算结果条件a
)。
获得具有N个对象的所需结果需要什么算法?
免责声明:建议的结构只是一个例子。您可以建议您认为可以实现结果的任何更改。我正在使用JavaScript(CoffeeScript)编程语言,但任何其他语言都可以。
答案 0 :(得分:0)
让我们首先以我们可以使用的格式获取数据。我们需要能够随意测试需求,而不仅仅是在实例化数据对象时:
{
id: 4
attributes: [
{ key: a, value: 2 }
{ key: d, value: 7 }
],
requirements: (sum) -> sum.b > 5 and sum.h < 10
}
虽然我们正在使用它,但让我们将属性置于更有用的状态(请注意,这不是必需的,但会使一切变得更简单):
{
id: 4
attributes: {
a: 2
d: 7
},
requirements: (sum) -> sum.b > 5 and sum.h < 10
}
现在我将介绍最简单且应该符合您需求的天真算法。从本质上讲,我们将继续循环遍历数据集,测试尚未使用的每一个数据集,如果它通过则将其添加到总和中。
changed = true
sum = {}
init(sum, items)
while changed
changed = false
for item in items
if !item.used && item.requirements(sum)
add(sum, item.attributes)
changed = true
item.used = true
我会让您填写add
和init
个功能。 add
一个应该很简单;它将第二个参数中的每个元素添加到第一个参数中的每个元素。 init
需要将sum
中可能使用(测试或添加到)的每个元素设置为0
。