печать всех элементов в n-мерном массиве, который пользователь вводит в C# - PullRequest
0 голосов
/ 13 марта 2020

Я хочу написать программу, которая получает массив из n измерений от пользователя (например, пользователь вводит массив 4 * 3 * 3 - три измерения) и печатает все его элементы (порядок не важен, может быть, все элементы более 1 непрерывной линии). Я смог добиться этого для массива из 3, но у меня нет ни малейшего понятия, с чего начать для любого массива измерения n.

Вот код на данный момент:

static void Main(string[] args)
        {
            int[,,] _numberGrid =
            {
                {
                    {1,2,3},
                    {4,5,6},
                    {7,8,9},
                },
                {
                    {1,2,3},
                    {4,5,6},
                    {7,8,9},
                },
                {
                    {1,2,3},
                    {4,5,6},
                    {7,8,9},
                },
                {
                    {1,2,3},
                    {4,5,6},
                    {7,8,9},
                },
                {
                    {1,2,3},
                    {4,5,6},
                    {7,8,9},
                }
            }; //4*3*3
            Console.WriteLine(_numberGrid.Rank);

            int numberOfDimentions = _numberGrid.Rank;
            int[] newArray = new int[_numberGrid.Rank];
            for (int i = 0; i<newArray.Length; i++)
            {
                newArray[i] = _numberGrid.GetUpperBound(i);
            }

            for(int i = 0; i <= newArray[0]; i++)
            {
                Console.Write("\n");
                for (int j = 0; j <= newArray[1]; j++)
                {
                    Console.Write("\n");
                    for (int k = 0; k <= newArray[2]; k++)
                    {
                        Console.Write(_numberGrid[i, j, k]);
                    }

                }
            }
            Console.ReadLine();
        }

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

Ответы [ 3 ]

2 голосов
/ 13 марта 2020

Просто используйте Array.Rank, Array.GetValue, Array.GetUpperBound и index array

Вот пример

Учитывая

public static bool Inc(int[,] array, int[] index)
{
   for (var i = 0; i < index.Length; i++)
      if (++index[i] > array.GetUpperBound(i))
         index[i] = 0;
      else
         return true;
   return false;
}

public static void Print(int[,] array, int[] index = null)
{
   index = index ?? new int[array.Rank];
   do Console.WriteLine(array.GetValue(index) + " = " + string.Join(",", index));
   while (Inc(array, index));
}

Использование

var test = new[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
Print(test);

Выход

1 = 0,0
3 = 1,0
5 = 2,0
7 = 3,0
2 = 0,1
4 = 1,1
6 = 2,1
8 = 3,1

Демонстрация онлайн


Примечание : я использовал в то время как l oop, хотя вы можете использовать рекурсию, это зависит от того, как вы хотите отобразить данные или что вы действительно хотите сделать

Вы также можете получить доступ к перечислителю многомерного массива чтобы получить каждый элемент

var test = new[,] { { 1, 2, 6 }, { 3, 4, 8 }, { 5, 6, 3 }, { 7, 8, 1  } };
foreach (var item in test)
   Console.WriteLine(item);

Выход

1
2
6
3
4
8
5
6
3
7
8
1
1 голос
/ 16 марта 2020

Это код, который я искал в C#

using System;
namespace _nd_arrays
{
    class Program
    {
        static void Main(string[] args)
        {
            int[,,,] _numGrid2 =
            {
                {
                    {
                        {0,2,3},
                        {1,0,3},
                        {1,2,0}
                    },

                    {
                        {11,22,33},
                        {44,55,66},
                        {77,88,99}
                    },
                },

                {
                    {
                        {1,0,3},
                        {1,2,0},
                        {0,2,3}
                    },

                    {
                        {111,222,333},
                        {111,222,333},
                        {111,222,33333}
                    },
                },
                {
                    {
                        {1,2,0},
                        {1,2,0},
                        {1,2,0}
                    },

                    {
                        {0,0,0},
                        {0,0,0},
                        {0,0,0}
                    },
                }
            };


            int[] ranks = new int[_numGrid2.Rank]; //index.length --> number of dimentiosn 
            //index items gives us the upper boud for each dimentino 
            for (int i= 0; i < _numGrid2.Rank; i++)
            {
                ranks[i] = _numGrid2.GetUpperBound(i);
            }
            int[] indeces = new int[_numGrid2.Rank];

            Console.WriteLine(PrintCustomArray(_numGrid2, ranks, indeces, 0));

            Console.ReadLine();
        }



        static string PrintCustomArray(Array _initialArray, int[] ranks, int[] printIndeces, int currentDimension )
        {
            string result = "";
            if(currentDimension == ranks.Length - 1)
            {
                for (int i = 0; i <= ranks[currentDimension]; i++)
                {
                    printIndeces[currentDimension] = i;

                    result = result + _initialArray.GetValue(printIndeces).ToString();
                }

            }

            else
            {                           //4
                for (int i = 0; i <= ranks[currentDimension]; i++)
                {
                    printIndeces[currentDimension] = i;
                                                                                    //              //
                    result = result + PrintCustomArray(_initialArray, ranks, printIndeces, currentDimension +1);
                }

            }



            return result;


        }
    }
}

, он будет печатать все элементы в n-мерном массиве в одну строку, используя рекурсию

ref: http://csharphelper.com/blog/2017/08/iterate-over-items-in-an-array-with-unknown-dimensions-in-c/

1 голос
/ 13 марта 2020

Несколько моментов, чтобы наметить решение:

Хранение : Вы не можете использовать стандартный n -мерный массив, так как n не известен во время компиляции. Есть как минимум два способа решения этой проблемы:

  1. Создайте собственную структуру данных NArray, которая состоит из массива либо ссылок на NArray (одного измерения меньше), либо базового типа данных (целое число).
  2. Используйте одномерный массив целых чисел и отслеживайте измерения «вручную», как n-мерные массивы фиксированного размера реализованы внутри. Например, для трехмерного массива измерений 5x3x3, как в вашем примере, вы будете отслеживать эти измерения [5,3,3] как массив переменного размера. Все, что вам нужно сделать, это создать функцию, которая преобразует многомерный индекс в одномерный.

Обратите внимание, что вариант 2, вероятно, будет более эффективным, но работает, только если измерения имеют фиксированный размер (как в вашем примере).

Ввод : Сначала вам необходимо получить размер и размеры. Для массивов фиксированного размера это может быть просто [5,3,3]. Впоследствии передайте числа таким образом, чтобы вы могли определить индексы, к которым они принадлежат. Для массивов фиксированного размера это могут быть просто числа по порядку (в конце концов, вы просто заполняете одномерный массив).

Выходные данные : как только вы получите структуру данных в место, печать должна быть довольно простой, используя рекурсию для подмассивов меньшего измерения.

Пример : Предположим, что мы используем подход с одномерным массивом с вашими данными выше, отображая 3 -размерный индекс [a, b, c] до a * 3 * 3 + b * 3 + c. Тогда функция печати может выглядеть примерно так:

void printArray(int[] data, int[] dimensions, int[] index) {
    if ( index.size == dimensions.size ) {
        print(data[map_to_1d(dimensions, index)] + ' ');
    } else {
        print('[ ');
        for (int i = 0; i < dimensions[index.size]; i++) {
            int[] subIndex = index + { i }; // append i
            printArray(data, dimensions, subindex);
        }
        print(']');
    }
}

PS: Другой подход, требующий меньшего количества реализации, может заключаться в использовании библиотеки для json объектов, которые включают многомерные массивы в качестве особого случая .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...