按照c#

时间:2015-11-16 18:09:55

标签: c# arrays sorting

我需要按照第一个元素的升序对2d数组行进行排序,例如

  

{{5,7,6},{2,9,6},{4,8,1}} - > {{2,9,6},{4,8,1},{5,7,6}}

我可以在行中找到最大元素,但我现在不知道如何对行进行排序。

public double[] maxInRow(double[,] n) 
 { 
    double[] result = new double[n.GetLength(0)]; 
    for (int i = 0; i < n.GetLength(0); i++) 
    { 
        double max = 0;
        for (int j = 0; j < n.GetLength(1); j++) 
        { 
        if (max < n[i,j]) 
        { 
            max = n[i,j];
        } 
        } 
    result[i] = max; 
    } 
return result; 
}

你能建议一下吗?

提前致谢!

6 个答案:

答案 0 :(得分:3)

可悲的是,对于那个sintax,你错过了linq的力量,这是.Net framework的最佳组成部分之一,你可以试试这个

double[][] x = new double[2][];
x[0] = new double[] { 5, 2, 5 };
x[1] = new double[] { 6, 8, 3 };
x[2] = new double[] { 8, 3, 6 };

var sortedByFisrtVal =  x.OrderBy(y => y[0]);
var sortedBySecondVal = x.OrderBy(y => y[1]);

//trying to guess maybe this is better
var sorted =  x.OrderBy(y => y[0]).ThenBy(y => y[1]).ThenBy(y => y[2]);

答案 1 :(得分:3)

如果性能不是很关键,那么你可以将2D数组转换为行数组,通过linq OrderBy对它们进行排序,以Max为标准,然后将结果转换回2D数组:

        private static T[][] Convert<T>(T[,] source, int firstDim, int secondDim)
        {
            T[][] result = new T[firstDim][];
            for (int i = 0; i < firstDim; i++)
            {
                T[] temp = new T[secondDim];    
                for (int j = 0; j < secondDim; j++)
                {
                    temp[j] = source[i, j];
                }

                result[i] = temp;
            }

            return result;
        }

        private static T[,] ConvertBack<T>(T[][] source, int firstDim, int secondDim)
        {
            var result = new T[firstDim, secondDim];
            for (int i = 0; i < firstDim; i++)
            {
                for (int j = 0; j < secondDim; j++)
                {    
                    result[i, j] = source[i][j];
                }
            }

            return result;
        }

        // usage sample
        double[,] array = { { 5, 7, 6 }, { 2, 9, 6 }, { 4, 8, 1 } };
        int firstDim = array.GetUpperBound(0) + 1;
        int secondDim = array.GetUpperBound(1) + 1;
        double[][] jagged = Convert(array, firstDim, secondDim);

        // actual sort is done here!
        double[][] sorted = jagged.OrderByDescending(row => row.Max()).ToArray();

        double[,] result = ConvertBack(sorted, firstDim, secondDim);

答案 2 :(得分:1)

你不需要任何额外的方法。如上所述,只为2d数组实现Sort方法。

此Sort算法与1D数组的Sort算法相同,但您还需要第三个循环来交换行的元素。

public static void Sort(double[,] n)
{
    for (int i = 0; i < n.GetLength(0) - 1; i++)
    {
        for (int j = i; j < n.GetLength(0); j++)
        {
            if (n[i, 0] > n[j, 0]) // sort by ascending by first index of each row
            {
                for (int k = 0; k < n.GetLength(1); k++)
                {
                    var temp = n[i, k];
                    n[i, k] = n[j, k];
                    n[j, k] = temp;
                }
            }
        }
    }
}

你可以这样称呼它。

Sort(your2dArray);

请注意,算法可能会变得非常慢,正如Alexei Levenkov所指出的那样。因此,如果性能在这里不重要,请使用它。

如果使用jagged array而不是2D数组,则可以更快地完成任务。此外,linq支持1D数组(因此也是锯齿状数组),它实现了IEnumerable,您可以使用OrderBy进行快速排序。

答案 3 :(得分:1)

2d数组不是用于排序,但无论如何,这是你如何做到的

public static class MyAlgorithms
{
    public static void SortByFirstColumn<T>(this T[,] array, IComparer<T> comparer = null)
    {
        // Indirect sorting
        var sortIndex = new int[array.GetLength(0)];
        for (int i = 0; i < sortIndex.Length; i++)
            sortIndex[i] = i;
        if (comparer == null) comparer = Comparer<T>.Default;
        Array.Sort(sortIndex, (a, b) => comparer.Compare(array[a, 0], array[b, 0]));
        // Reorder the array using "in situ" algorithm
        var temp = new T[array.GetLength(1)];
        for (int i = 0; i < sortIndex.Length; i++)
        {
            if (sortIndex[i] == i) continue;
            for (int c = 0; c < temp.Length; c++)
                temp[c] = array[i, c];
            int j = i;
            while (true)
            {
                int k = sortIndex[j];
                sortIndex[j] = j;
                if (k == i) break;
                for (int c = 0; c < temp.Length; c++)
                    array[j, c] = array[k, c];
                j = k;
            }
            for (int c = 0; c < temp.Length; c++)
                array[j, c] = temp[c];
        }
    }
}

并按如下方式使用

double[,] data = { { 5, 7, 6 }, { 2, 9, 6 }, { 4, 8, 1 } };
data.SortByFirstColumn();

此实施不会受到影响。有关其工作原理以及其他一些选项的详细说明,请参阅我对How can I sort a large 2d array C#

的回答

答案 4 :(得分:1)

如果您想按第一列排序,然后按第二列排序,再按第三列排序,依此类推所有列,您可以这样:

void Main()
{
    var input = new double[,] {{5,7,6},{2,9,6},{2,5,6},{4,8,1}};

    Sort(input);
    // Input is now:
    // {{2,5,6},{2,9,6},{4,8,1},{5,7,6}}
}

public T[,] Sort<T>(T[,] data) where T : IComparable
{
    // Transform to array of arrays.
    var rows = new T[data.GetLength(0)][];
    for (var i = 0; i< data.GetLength(0); ++i)
    {
        rows[i] = new T[data.GetLength(1)];
        for (var j = 0; j < data.GetLength(1); ++j)
            rows[i][j] = data[i, j];
    }

    // Sort rows using a custom array comparer.
    Array.Sort(rows, new ArrayComparer<T>());

    // Write data back to input array.
    for (var i = 0; i< data.GetLength(0); ++i)
        for (var j = 0; j < data.GetLength(1); ++j)
            data[i, j] = rows[i][j];

    return data;
}

public class ArrayComparer<T> : IComparer<T[]> where T : IComparable
{
    public int Compare(T[] x, T[] y)
    {
        var comparer = Comparer<T>.Default;

        // Compare elements as long as they're different.
        for(var i = 0; i < x.Length; ++i)
        {
            var compareResult = comparer.Compare(x[i], y[i]);
            if (compareResult != 0) return compareResult;
        }
        return 0;
    }
}

答案 5 :(得分:0)

Array.Sort(double, (a,b)=>{return a[0]-b[0];});