为什么我为同一设计得到两个不同的结果?

时间:2016-07-27 20:36:42

标签: c# algorithm sorting design-patterns logic

快速提问:

我有一堆(云)坐标,我倾向于找到整个群的四个角坐标。在角落里我的意思是:

  

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)

enter image description here

1 个答案:

答案 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))的相对顺序。排序算法可能会交换它们的位置。