基于最小坐标标准对点列表进行排序

时间:2015-01-15 18:47:25

标签: c# list sorting criteria min

我希望你能帮我解决这个问题。我必须做一些"特殊排序"作为较大代码的一部分的点列表(x,y,z坐标)。

此列表(按定义)将:

i)总是有一列所有值都等于零。

ii)第一点和最后一点始终相同。

列表的排序取决于哪一列等于零。我可以自己识别这个专栏没有问题(参见代码)但是当它与排序位一起时我很挣扎。首先,我必须找到符合某些特定标准的要点,然后根据此重新组织列表。我已经将排序标准解释为代码中的注释(参见第2节和第3节)。

如果你可以提供2)和3)的帮助那将是很好的(我认为第一部分是好的)。

非常感谢

代码:

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{

[STAThread]

public static void Main(string[] args)
{
    //Populating the list
    var ListPoints = new List<double[]>();

    double[] P0 = { 10, 10, 0 };
    double[] P1 = { 10, 0, 0 };
    double[] P2 = { 0, 0, 0 };
    double[] P3 = { 0, 10, 0 };

    ListPoints.Add(P0);
    ListPoints.Add(P1);
    ListPoints.Add(P2);
    ListPoints.Add(P3);
    ListPoints.Add(P0);

    ///This list (by definition) will: 
    /// i) Always have a column with all the values equal zero
    /// ii) The first and the last point will always be the same. 
    ///We need to detect the column with all values = zero, because the list sorting will depend on this. 



    /// 1) Detect which columns has all values equal to zero using the columnZero variable
    var counterX = new List<int>();
    var counterY = new List<int>();
    var counterZ = new List<int>();


    for (int i = 0; i < ListPoints.Count - 1; i++)
    {
        //First column with all values equal zero
        if (ListPoints[i][0] == 0 && ListPoints[i][0] == ListPoints[i + 1][0]) { counterX.Add(1); }
        //Second column with all values equal zero
        if (ListPoints[i][1] == 0 && ListPoints[i][1] == ListPoints[i + 1][1]) { counterY.Add(1); }
        //Third column with all values equal zero
        if (ListPoints[i][2] == 0 && ListPoints[i][2] == ListPoints[i + 1][2]) { counterZ.Add(1); }
    }

    if (counterX.Count == ListPoints.Count - 1)
    { Console.WriteLine("all points of the 1st column are zero");}

    if (counterY.Count == ListPoints.Count - 1)
    { Console.WriteLine("all points of the 2nd column are zero");}

    if (counterZ.Count == ListPoints.Count - 1)
    { Console.WriteLine("all points of the 3rd column are zero");}

    /// 2) Now a point "Q" must be found in the list according to this:
    /// 2.1/ If the first column has all values = zero:
    ///      Find the row index of the smallest value in the second column.
    ///         If there are several rows in the second column with the same minimum value go and find between those which one has the smallest value in the third column.
    ///         If there is only one value in the second column keep that one.
    /// 2.2/ If the second column has all values = zero:
    ///      Find the row index of the smallest value in the first column.
    ///         If there are several rows in the first column with the same minimum value go and find between those which one has the smallest value in the third column.
    ///         If there is only one value in the first column keep that one.
    /// 2.3/ If the third column has all values = zero:
    ///      Find the row index of the smallest value in the first column.
    ///         If there are several rows in the first column with the same minimum value go and find between those which one has the smallest value in the second column.
    ///         If there is only one value in the first column keep that one.
    ///

    /// 3) Once this value has been found we have to put the list starting by this point "Q", then copy the previous values at the end of the list  and finally add again "Q". 
    ///    Example:The column with all values = 0  is column 3 and the generic point "Q" is the point "P2" in my list. The input is P0-P1-P2-P3-P0 but I want to have it P2-P3-P0-P1-P2.
}
}

1 个答案:

答案 0 :(得分:0)

根据您的标准,排序算法的前两点退化为一个更简单的算法。

即:无论哪一列都是0,您总是按第一列排序,然后按第二列排序,然后按第三列升序值排序。这会将您的目标项目留在列表的开头,然后从那里获取原始列表中的正确顺序。

private List<double[]> SpecialSort(List<double[]> list)
{
  // Make an editable duplicate of your original list and remove the duplicated array at the start (or end) of the list.
  List<double[]> orig = new List<double[]>(list);
  orig.RemoveAt(0);

  // Copy and sort the list by 1st column, 2nd column, 3rd column.
  List<double[]> copy = orig.OrderBy(p => p[0]).ThenBy(p => p[1]).ThenBy(p => p[2]).ToList();

  // The first item in the copy-sorted list is your point "Q".
  // Find its index in the original list.
  int index = orig.IndexOf(copy[0]);
  List<double[]> sorted = new List<double[]>();

  // For the list count + 1 (adding point Q twice) add the original list
  // objects in the correct order, starting at "point'Q'".
  for (int i = 0; i <= orig.Count; i++)
  {
    sorted.Add(orig[(index + i) % orig.Count]);
  }

  return sorted;
}

然后打电话给

ListPoints = this.SpecialSort(ListPoints);