none
Элементы класса Array для двумерного массива RRS feed

  • Вопрос

  • Здраствуйте!!!

    Имеется двумерный массив:

    int [,] a=new int[3,3]{{24, 50, 18 },{ 7, 9, -1 },{ 6, 15, 3}}; //Двумерный массив
    Можно ли для этого массива применить  методы класса Array, такие как Sort, IndexOf, Reverse?
    Я понимаю что эти методы , применяются для одномерного массива.

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

    Если есть, то пожалуйста приведите примеры для двумерного массива.


    Заранее спасибо за ответ!!!
    • Перемещено Siddharth Chavan 1 октября 2010 г. 22:03 MSDN Forums Consolidation (От:Visual C#)
    3 ноября 2009 г. 6:06

Ответы

  • 1 способ
                //int[,] --> int[]
                int[,] a = {{1, 2}, {3, 4}};
                
                int[] b = new int[4];
    
                for (int i = 0; i < 2; i++)
                    for (int j = 0; j < 2; j++)
                        b[2 * i + j] = a[i, j];
    
                foreach (int x in b)
                {
                    Console.WriteLine(x);
                }
                //------------------------------------
                for (int i = 0; i < 4; i++)
                {
                    b[i]++;
                }
    
                //int[] -> int[,]
                //----------------------------------
                for (int i = 0; i < 2; i++)
                    for (int j = 0; j < 2; j++)
                        a[i, j] = b[2 * i + j];
                for (int i = 0; i < 2; i++)
                {
                    for (int j = 0; j < 2; j++)
                        Console.Write(a[i, j] + " ");
                    Console.WriteLine();
                }
    
    2способ
                System.Collections.IEnumerator en = a.GetEnumerator();
                int ii = 0;
                while (en.MoveNext() && en.Current != null)
                {
                    b[ii++] = (int)en.Current;
                }
                foreach (int x in b)
                {
                    Console.WriteLine(x);
                }
    
    
    Возможно имеются и встроенные методы, но они мне не встречались. На самом деле преобразования подобного рода тривиальны.
    • Помечено в качестве ответа Druny 3 ноября 2009 г. 11:06
    3 ноября 2009 г. 9:30
  • Для ступенчатого массива:
    namespace ConsoleApplication12
    {

        public class ArrayComparer : System.Collections.IComparer
        {
            int ix;
            public ArrayComparer(int SortFieldIndex)
            {
                ix = SortFieldIndex;
            }

            public int Compare(object x, object y)
            {
                IComparable cx = (IComparable)((Array)x).GetValue(ix);
                IComparable cy = (IComparable)((Array)y).GetValue(ix);
                return cx.CompareTo(cy);
            }
        }
       
        class Program
        {
           
            static void Main(string[] args)
            {


                int[][] lines = new int[4][];
                lines[0] = new int[] { 1, 5, 2 };
                lines[1] = new int[] { 2, 8, 7 };
                lines[2] = new int[] { 5, 1, 5 };
                lines[3] = new int[] { 4, 6, 4 };

                foreach (int[] line in lines)
                {
                    Console.WriteLine(line[2]);
                }
                System.Array.Sort(lines, new ArrayComparer(2));
               
                foreach (int[] line in lines)
                {
                    Console.WriteLine(line[2]);
                }
                Console.ReadLine();     
            }
        }
    }

    Сортировка строк согласно столбцам..В примере указан 3 столбец, значит исходный массив
                { 1, 5, 2 }
                { 2, 8, 7 }
                { 5, 1, 5 }
                { 4, 6, 4 }
    Примет значение
                { 1, 5, 2 }
                { 4, 6, 4 }           
                { 5, 1, 5 }
                { 2, 8, 7 }
               
               
    • Помечено в качестве ответа Druny 3 ноября 2009 г. 11:06
    3 ноября 2009 г. 10:05

Все ответы

  • Как вариант - если хотите воспользоваться средствами класса Array - можно преобразовать двумерный массив в одномерный, выполнить операции, затем преобразовать обратно.
    3 ноября 2009 г. 8:31
  • Как вариант - если хотите воспользоваться средствами класса Array - можно преобразовать двумерный массив в одномерный, выполнить операции, затем преобразовать обратно.
    Отличная идея и всё возможно реализовать, только это дело принципа использования методов Array имхо..=)
    3 ноября 2009 г. 8:34
  • А как преобразовать двумерный массив в одномерный?

    Приведи пример!!!
    3 ноября 2009 г. 8:55
  • Запомнить длину, ширину и переписать построчно в одномерный...=)
    3 ноября 2009 г. 9:10
  • Блин так это же запаришся, неужели нет методов класса Array которые работают с двумерным массивом(Упорядочивают, Ищут .....)?
    Ты довал выше ссылки там не понятно как-то, и с английским у меня плохо

    Не мог бы сам привести простой пример !!!

    Ну не запаришся просто не удобно!!!!!!

    • Изменено I.Vorontsov 3 ноября 2009 г. 9:40 Выражать мысль надо одним постом
    3 ноября 2009 г. 9:18
  • 1 способ
                //int[,] --> int[]
                int[,] a = {{1, 2}, {3, 4}};
                
                int[] b = new int[4];
    
                for (int i = 0; i < 2; i++)
                    for (int j = 0; j < 2; j++)
                        b[2 * i + j] = a[i, j];
    
                foreach (int x in b)
                {
                    Console.WriteLine(x);
                }
                //------------------------------------
                for (int i = 0; i < 4; i++)
                {
                    b[i]++;
                }
    
                //int[] -> int[,]
                //----------------------------------
                for (int i = 0; i < 2; i++)
                    for (int j = 0; j < 2; j++)
                        a[i, j] = b[2 * i + j];
                for (int i = 0; i < 2; i++)
                {
                    for (int j = 0; j < 2; j++)
                        Console.Write(a[i, j] + " ");
                    Console.WriteLine();
                }
    
    2способ
                System.Collections.IEnumerator en = a.GetEnumerator();
                int ii = 0;
                while (en.MoveNext() && en.Current != null)
                {
                    b[ii++] = (int)en.Current;
                }
                foreach (int x in b)
                {
                    Console.WriteLine(x);
                }
    
    
    Возможно имеются и встроенные методы, но они мне не встречались. На самом деле преобразования подобного рода тривиальны.
    • Помечено в качестве ответа Druny 3 ноября 2009 г. 11:06
    3 ноября 2009 г. 9:30
  • Для ступенчатого массива:
    namespace ConsoleApplication12
    {

        public class ArrayComparer : System.Collections.IComparer
        {
            int ix;
            public ArrayComparer(int SortFieldIndex)
            {
                ix = SortFieldIndex;
            }

            public int Compare(object x, object y)
            {
                IComparable cx = (IComparable)((Array)x).GetValue(ix);
                IComparable cy = (IComparable)((Array)y).GetValue(ix);
                return cx.CompareTo(cy);
            }
        }
       
        class Program
        {
           
            static void Main(string[] args)
            {


                int[][] lines = new int[4][];
                lines[0] = new int[] { 1, 5, 2 };
                lines[1] = new int[] { 2, 8, 7 };
                lines[2] = new int[] { 5, 1, 5 };
                lines[3] = new int[] { 4, 6, 4 };

                foreach (int[] line in lines)
                {
                    Console.WriteLine(line[2]);
                }
                System.Array.Sort(lines, new ArrayComparer(2));
               
                foreach (int[] line in lines)
                {
                    Console.WriteLine(line[2]);
                }
                Console.ReadLine();     
            }
        }
    }

    Сортировка строк согласно столбцам..В примере указан 3 столбец, значит исходный массив
                { 1, 5, 2 }
                { 2, 8, 7 }
                { 5, 1, 5 }
                { 4, 6, 4 }
    Примет значение
                { 1, 5, 2 }
                { 4, 6, 4 }           
                { 5, 1, 5 }
                { 2, 8, 7 }
               
               
    • Помечено в качестве ответа Druny 3 ноября 2009 г. 11:06
    3 ноября 2009 г. 10:05
  • Есть 2 варианта в зависимости от цели:
    • Если необходимо отсортировать весь массив, то лучше сконвертировать его в одномерный, затем отсортировать, после этого обратно. Это можно сделать например так (обобщённые методы-расширения): 
      public static T[] ToOneDimensional<T>(this T[,] array)
      {
          long width = array.GetLongLength(0);
          long height = array.GetLongLength(1);
      
          T[] result = new T[width * height];
      
          for (long i = 0; i < width; i++)
          {
              for (long j = 0; j < height; j++)
              {
                  result[i * height + j] = array[i, j];
              }
          }
      
          return result;
      }
      
      public static T[,] ToMultidimensional<T>(this T[] array, int width, int height)
      {
          if (array.LongLength != width * height)
              throw new ArgumentException("Invalid array: size must be equal to width * height.", "array");
      
          T[,] result = new T[width, height];
      
          for (int i = 0; i < width; i++)
          {
              for (int j = 0; j < height; j++)
              {
                  result[i, j] = array[i * height + j];
              }
          }
      
          return result;
      }
    • Если же необходимо отсортировать только отдельную строку или столбец, то лучше сконвертировать массив в ступенчатый, например так (с помощью тех же методов-расширений): 
      public static T[][] ToJagged<T>(this T[,] array, bool firstDimensionOnTop)
      {
          long width = array.GetLongLength(firstDimensionOnTop ? 0 : 1);
          long height = array.GetLongLength(firstDimensionOnTop ? 1 : 0);
      
          T[][] result = new T[width][];
      
          for (long i = 0; i < width; i++)
          {
              result[i] = new T[height];
              for (long j = 0; j < height; j++)
              {
                  result[i][j] = firstDimensionOnTop ? array[i, j] : array[j, i];
              }
          }
      
          return result;
      }
      
      public static T[,] ToMultidimensional<T>(this T[][] array, bool topArrayOnFirstDimension)
      {
          long width = array.LongLength;
          if (width == 0)
              return new T[0, 0];
      
          long height = array[0].LongLength;
      
          T[,] result = topArrayOnFirstDimension ? new T[width, height] : new T[height, width];
      
          for (long i = 0; i < width; i++)
          {
              if (array[i].LongLength != height)
                  throw new ArgumentException("Invalid array: all subarrays must have equal length.", "array");
              
              for (long j = 0; j < height; j++)
              {
                  if (topArrayOnFirstDimension)
                      result[i, j] = array[i][j];
                  else
                      result[j, i] = array[i][j];
              }
          }
      
          return result;
      }
      Где firstDimensionOnTop - указание на то, что нужно брать столбцы, а не строки; topArrayOnFirstDimension - для строк брать корневой массив, а для столбцов - вложенные.
    Вот пример использования этих методов:
    int[,] arr = new int[3, 4]
    {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12},
    };
    
    int[][] jagged = arr.ToJagged(true);
    foreach (var jag in jagged)
    {
        foreach (int val in jag)
        {
            Console.Write(val + " ");
        }
        Console.WriteLine();
    }
    Console.WriteLine();
    
    int[,] multi = jagged.ToMultidimensional(true);
    for (int i = 0; i < multi.GetLength(0); i++)
    {
        for (int j = 0; j < multi.GetLength(1); j++)
        {
            Console.Write(multi[i, j] + " ");
        }
        Console.WriteLine();
    }
    Console.WriteLine();
    
    int[] one = multi.ToOneDimensional();
    foreach (int val in one)
    {
        Console.Write(val + " ");
    }
    Console.WriteLine(Environment.NewLine);
    
    int[,] newMulti = one.ToMultidimensional(3, 4);
    for (int i = 0; i < newMulti.GetLength(0); i++)
    {
        for (int j = 0; j < newMulti.GetLength(1); j++)
        {
            Console.Write(newMulti[i, j] + " ");
        }
        Console.WriteLine();
    }

    5 ноября 2009 г. 21:53