快速提问:
我有一堆(云)坐标,我倾向于找到整个群的四个角坐标。在角落里我的意思是:
MyDesiredResult = {SmallestX,BiggestY,BiggestX,SmallestY}
我使用旧例程来获取我的值,是正确的:
double smallestX = MyCloud[0].X; // assing X of first element to my result controller
var tempCoordPoint = MyCloud[0]; // assign first element to my result controller
for (int i = 0; i < MyCloud.Count; i++)
{
if (smallestX > MyCloud[i].X) // find minimum X
{
smallestX = MyCloud[i].X;
tempCoordPoint = MyCloud[i];
}
}
MyResult.Add(tempCoordPoint); // add to my list
但是,我需要这样做四次(对于四个结果)。所以我试图通过将其更改为仅使用一次的 New Routine 来优化我的代码:
List<CoordPoint> MySortedList = MyCloud.Select(c => new CoordPoint { X = c.X, Y = c.Y, Z = c.Z, Color = c.Color }).ToList();
MySortedList.Sort((c1, c2) => c1.X.CompareTo(c2.X)); // sort on X
var temp = MySortedList[MySortedList.Count - 1]; // hold biggest X in a temp variable
MyResult.Add(MySortedList[0]); // add smallest X to my result
MySortedList.Sort((c1, c2) => c1.Y.CompareTo(c2.Y)); ; // sort on Y
MyResult.Add(MySortedList[MySortedList.Count - 1]); // add biggest Y to my result
MyResult.Add(temp); // add biggest X to my result
MyResult.Add(MySortedList[0]); // add smallest Y to my result
但它给出了不同的结果。我想显示一个示例输入,当前输出和所需的输出。我可以跳过示例输入(巨大负载)并显示结果。谁能指出我做错了什么?
对于相同的输入:
来自旧例程的结果:
(0,4),(15,12),(23,6),(19,0)
新常规的结果:
(0,4),(18,12),(23,6),(18,0)
答案 0 :(得分:2)
我将用另一个问题回答你的问题:
如果两个点具有相同的Y坐标并且Y坐标恰好是最小值或最大值,会发生什么?同样对于X坐标?
让我举一个例子来说明。假设你有这四点:
(0,0),(1,0),(0,1),(1,1)
您的原始算法将返回:
(0,0),(0,1),(1,0),(0,0)
现在让我们说我们取了原来的4分并将它们拖垮了:
(1,1),(0,1),(1,0),(0,0)
如果你运行原始算法,你会得到这个:
(0,1),(1,1),(1,1),(1,0)
根据你的说法,原始算法是正确的,但我只是在两个不同的顺序中给出了相同的点集,并得到了两个不同的答案。那么哪个答案是正确的?实际预期结果是什么?
现在,有一个原因我没有提供新算法的结果,那是因为我不知道你的新算法会产生什么。我不知道的原因是List<T>.Sort
执行不稳定的排序。这意味着比较“相等”的两个元素不一定按顺序排列。因此,如果我们的输入为(0, 0), (1, 0), (0, 1), (1, 1)
,则在尝试按X坐标排序后,以下所有内容都是有效的可能性:
(0,0),(0,1),(1,0),(1,1)
(0,1),(0,0),(1,0),(1,1)
(0,1),(0,0),(1,1),(1,0)
(0,0),(0,1),(1,1),(1,0)
List<T>.Sort
可以产生任何一个。如果您有更多重复的X坐标,您将有更多可能的排序。这被称为不稳定的原因是因为在排序之后不保留两个相等元素(例如(0, 0)
和(0, 1)
)的相对顺序。排序算法可能会交换它们的位置。