我需要按照第一个元素的升序对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;
}
你能建议一下吗?
提前致谢!
答案 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];});