我有一个对象列表,其中包含变量X、Y和Z。所有对象都是双精度的。现在,我想在一个特定的范围内选择对象,这些对象之间的关系仅基于X。我需要为这个范围内的所有对象分配平均X值,并保持所有成员的Y和Z不变。
我使用“simple”.Sort()对列表进行排序,因为X是第一个。.例如,(仅提及对象中的X变量)。
1013 1500 2200 2240 2251 2290 3100 3500
现在,我需要检查列表中的对象,比如100个。在这个例子中是:2200 2240 2251 2290
我已经尝试使用索引列表作为一个开始
if (DPlace2[i + 1].X - DPlace2[i].X < 100)
{
DPlace2[i].X = DPlace2[i].X + ((DPlace2[i + 1].X - DPlace2[i].X) / 2);
DPlace2[i + 1].X = DPlace2[i + 1].X - ((DPlace2[i + 1].X - DPlace2[i].X) / 2);
}
字符串
但是在这个范围内可能有任何数量的对象,所以解决方案是垃圾。什么是最好的解决方案?
编辑:为了澄清,这里有一个List代表我的问题的例子。(我最初的问题是一个对象列表,其中需要属性X的值,但这个例子只是显示int以使其更容易阅读。)
List<int> DPlace3 = new List<int>()
{
1175,
1575,
2010, //->2015
2010, //->2015
2020, //->2015
3089,
5050, //->5055
5060, //->5055
8100
};
型
带注解的值表示相对于彼此在100的 * 范围 * 内的对象。也许“范围”在我的问题中是一个草率的表达。对不起!这些行上的注解表示我希望代码将值更改为什么。这就是为什么我对列表进行排序,并开始尝试使用列表中成员的索引,并检查下一个值是否小于100(即范围)从前一个。如果是这样,将索引i的值更改为当前和下一个的平均值。如果范围内总是有2个对象,这很好用,但它可以是5。在上面的例子中,第一个范围涉及3个对象,第二个范围包括2个对象。所以,我在想,一定有一种方法可以很好地编写这个代码。这是一个相当新的东西,所以我不知道SlidingWindow是什么。:)
而且它也是草率的状态“平均值”,因为它是平均值的只有最小/最大值发现在每个值范围.
编辑2:找到了我的问题的解决方案,但它是根据我的特定需求“硬编码”的,肯定不是最优化的(?)对我来说,在值范围内最多可以有8个对象(就目前而言)。所以,我这样做了我的循环:
for (int i = 0; i < DPlace2.Count - 1; i++)
{
if (((i+7) < DPlace2.Count) && DPlace2[i + 7].X - DPlace2[i].X < 150)
{
DPlace2[i].X = DPlace2[i].X + ((DPlace2[i + 7].X - DPlace2[i].X) / 2);
DPlace2[i + 1].X = DPlace2[i].X;
DPlace2[i + 2].X = DPlace2[i].X;
DPlace2[i + 3].X = DPlace2[i].X;
DPlace2[i + 4].X = DPlace2[i].X;
DPlace2[i + 5].X = DPlace2[i].X;
DPlace2[i + 6].X = DPlace2[i].X;
DPlace2[i + 7].X = DPlace2[i].X;
i = i + 6;
}
if (((i + 6) < DPlace2.Count) && DPlace2[i + 6].X - DPlace2[i].X < 150)
{
DPlace2[i].X = DPlace2[i].X + ((DPlace2[i + 6].X - DPlace2[i].X) / 2);
DPlace2[i + 1].X = DPlace2[i].X;
DPlace2[i + 2].X = DPlace2[i].X;
DPlace2[i + 3].X = DPlace2[i].X;
DPlace2[i + 4].X = DPlace2[i].X;
DPlace2[i + 5].X = DPlace2[i].X;
DPlace2[i + 6].X = DPlace2[i].X;
i = i + 5;
}
if (((i + 5) < DPlace2.Count) && DPlace2[i + 5].X - DPlace2[i].X < 150)
{
DPlace2[i].X = DPlace2[i].X + ((DPlace2[i + 5].X - DPlace2[i].X) / 2);
DPlace2[i + 1].X = DPlace2[i].X;
DPlace2[i + 2].X = DPlace2[i].X;
DPlace2[i + 3].X = DPlace2[i].X;
DPlace2[i + 4].X = DPlace2[i].X;
DPlace2[i + 5].X = DPlace2[i].X;
i = i + 4;
}
if (((i + 4) < DPlace2.Count) && DPlace2[i + 4].X - DPlace2[i].X < 150)
{
DPlace2[i].X = DPlace2[i].X + ((DPlace2[i + 4].X - DPlace2[i].X) / 2);
DPlace2[i + 1].X = DPlace2[i].X;
DPlace2[i + 2].X = DPlace2[i].X;
DPlace2[i + 3].X = DPlace2[i].X;
DPlace2[i + 4].X = DPlace2[i].X;
i = i + 3;
}
if (((i + 3) < DPlace2.Count) && DPlace2[i + 3].X - DPlace2[i].X < 150)
{
DPlace2[i].X = DPlace2[i].X + ((DPlace2[i + 3].X - DPlace2[i].X) / 2);
DPlace2[i + 1].X = DPlace2[i].X;
DPlace2[i + 2].X = DPlace2[i].X;
DPlace2[i + 3].X = DPlace2[i].X;
i = i + 2;
}
if (((i + 2) < DPlace2.Count) && DPlace2[i + 2].X - DPlace2[i].X < 150)
{
DPlace2[i].X = DPlace2[i].X + ((DPlace2[i + 2].X - DPlace2[i].X) / 2);
DPlace2[i + 1].X = DPlace2[i].X;
DPlace2[i + 2].X = DPlace2[i].X;
i++;
}
if (DPlace2[i + 1].X - DPlace2[i].X < 150)
{
DPlace2[i].X = DPlace2[i].X + ((DPlace2[i + 1].X - DPlace2[i].X) / 2);
DPlace2[i + 1].X = DPlace2[i].X;
}
}
型
由于列表是排序的,所以min-value总是来自object[i],而max value是来自满足范围内标准的最后一个对象。平均值是从这两个“极值”计算的,因此我的“解决方案”中的所有循环。速度是一个问题,所以我试图通过增加i来停止不必要的循环。即使我认为我现在已经解决了我的问题,无论如何,这都不是一个最优的解决方案。明天可能有9个可能的条目,而不是8个...当然,这个问题一定有一个通用的解决方案。
1条答案
按热度按时间2vuwiymt1#
我想这可能有点复杂,但它似乎是有效的:
因此,在这个解决方案中,我创建了一个执行转换的类。
它的操作假设输入之前已经按X排序,就像它在问题中一样。
该算法基本上是:
然后将其添加到花名册并继续
字符串
在行动:https://dotnetfiddle.net/HMfK53
根据问题中的输入:
型