2015-05-21 4 views
3

Предположим, я создаю этот код для генерации idv-го случайного числа. Но мне сложно сортировать массив, зависит от последнего столбца.Сортировка столбцов многомерных массивов

скажем, что индивидуальный размер [idv, width] = [8,6] , и я хочу отсортировать всю строку со столбцом 6-го ... и я хочу взять 4 верхний список в массиве после него отсортирован. Как я могу реализовать этот случай для кода?

public static void population(double[,] individual, int width, int idv, Random rnd) 
    { 
     for (int i = 0; i < idv; i++) 
     { 
      Console.Write("individual {0} :\t", i+1); 
      for (int j = 0; j < width; j++) 
      { 
       individual[i, j] = Math.Round(rnd.NextDouble() * 10, 2); 
       Console.Write("{0} ", individual[i, j]); 
      } 
      Console.WriteLine("\n"); 
     } 
    } 

Спасибо

+1

Предлагаю использовать * зубчатые массивы * 'double [] [] individual' вместо 2d. –

+0

как 'Дмитрий' написал. многомерные массивы - это полупеченная/неполная «подсистема». – xanatos

ответ

3

Я предлагаю вам с помощью неровных массивовdouble[][] вместо 2d тех double[,]. Jagged массив просто массив из массивов, которые вы можете легко сортировать, фильтровать и т.д., как правило, с помощью Linq:

double[][] individual = new double[][] { 
    new double[] {81, 82, 83, 84, 85, 86}, 
    new double[] {11, 12, 13, 14, 15, 16}, 
    new double[] {41, 42, 43, 44, 45, 46}, 
    new double[] {31, 32, 33, 34, 35, 36}, 
    new double[] {51, 52, 53, 54, 55, 56}, 
    new double[] {21, 22, 23, 24, 25, 26}, 
    new double[] {61, 62, 63, 64, 65, 66}, 
    new double[] {71, 72, 73, 74, 75, 76}, 
    }; 

    double[][] fragment = individual 
    .OrderBy(line => line[line.GetUpperBound(0)]) // by last column 
    .Take(4) 
    .ToArray(); 

еще один Linq, чтобы проверить результаты:

String test = String.Join(Environment.NewLine, fragment 
    .Select(line => String.Join("\t", line))); 

    Console.Write(test); 

в результате

11 12 13 14 15 16 
21 22 23 24 25 26 
31 32 33 34 35 36 
41 42 43 44 45 46 
2

при использовании многомерных массивов, нет простого способа работать с ними с помощью LINQ, вам нужно будет положиться на старый добрый for.

static void Main() 
{ 
    // Input array 
    double[,] u = { 
     { 1, 9, 3 }, 
     { 0, 3, 4 }, 
     { 3, 4, 5 }, 
     { 3, 6, 8 }, 
     { 3, 5, 7 }, 
    }; 

    // Get dimension sizes, specify column to order by 
    int count = u.GetLength(0), length = u.GetLength(1), orderBy = 2; 
    // Result array 
    double[,] v = new double[count, length]; 
    // Construct a list of indices to sort by 
    var indices = Enumerable.Range(0, count).OrderBy(i => u[i, orderBy]).ToList(); 
    // Copy values from input to output array, based on these indices 
    for (int i = 0; i < count; i++) 
     for (int j = 0; j < length; j++) 
      v[i, j] = u[indices[i], j]; 

    PrintArray(u); 
    Console.WriteLine(); 
    PrintArray(v); 
} 

static void PrintArray (double[,] a) 
{ 
    for (int i = 0; i < a.GetLength(0); i++) { 
     for (int j = 0; j < a.GetLength(1); j++) 
      Console.Write(a[i, j]); 
     Console.WriteLine(); 
    } 
} 

Если вам нужны только верхние 4 строки, вы можете добавить Take(4) до того ToList() вызова и настроить результат создания массива и копирование значений в него соответствующим образом.

Многоэлементные массивы более эффективны и используют меньше памяти, поэтому, если ваши массивы достаточно велики или вам нужно работать с ними быстрее, вам может потребоваться написать немного больше кода и использовать многомерные матрицы, а не массивы с зазубринами, которые проще работать с.

0

Для прямоугольной матрицы [,] вы можете скопировать нужный столбец в одномерном массиве вместе с индексами, отсортировать его, а затем получить строки с первыми 4 индексами.

static IEnumerable<Tuple<int, double>> GetColumn(int columnIndex, double[,] a) 
{ 
    for (int i = a.GetLowerBound(0); i <= a.GetUpperBound(0); i++) 
     yield return Tuple.Create(i, a[i, columnIndex]); 
} 

double [,] data = ...; 
var column = GetColumn(4, data); 
var top4Indices = column.OrderBy(v => v.Second) 
         .Take(4) 
         .Select(v => v.First); 

foreach (int i in top4Indices) 
    for (int j = data.GetLowerBound(1); j <= data.GetUpperBound(1); j++) 
     data[i, j]... 
Смежные вопросы