Пример создания класса для работы с двухмерными массивами

Для практики программирования Вам были предложены Задачи 2, содержащие работу с двухмерными массивами.
Полезно эти программы писать в стиле ООП, то есть задается некоторый исходный класс, назовем его ArrayIntTwo, с использованием которого далее решаются поставленные задачи.
Вы можете добавлять в этот класс новые методы, либо, наследуя от него дочерний класс, создать новый.

Решение

1. Каждый класс будем сохранять как отдельный файл в общем пространстве имен, например, namespace ArrayIntTwo, либо через подключение через директиву using.
2. Исходный класс назовем ArrayInt2, который будет содержать некоторые поля, конструкторы и методы. Естественно, что полями класса будут число строк и столбцов двухмерного массива nr и nc, и собственно массив a[,]. Конструкторы класса необходимы для создания массивов разными способами (через ввод с клавиатуры, через генераторы случайных чисел). Методы класса — самые простые (задать или извлечь элемент массива, найти максимальный/минимальный элемент и т.п.). тогда получим:

// класс ArrayInt2 - двухмерный массив целых чисел
using System;
namespace TArrayIntTwo
{
    public class ArrayInt2
    {
        protected int nr;  // число строк
        protected int nc;  // число столбцов
        protected int[,] a;         // двухмерный массив целых чисел

        // конструктор для ввода массива с клавиатуры
        public ArrayInt2(int N_Rows, int N_Columns)
        {
            nr = N_Rows;
            nc = N_Columns;
            a = new int[nr, nc];
            Console.WriteLine("Введите по строкам {0}x{1} элементов целочисленного двухмерного массива", nr, nc);
            for (int i = 0; i < nr; i++)
                for (int j = 0; j < nc; j++)
                {
                    Console.Write("a[{0},{1}]: ", i, j);
                    a[i, j] = Convert.ToInt32(Console.ReadLine());
                }
        }

        // конструктор с генератором случайных чисел от 0 до max
        public ArrayInt2(int NR, int NC, int max)
        {
            Random rnd = new Random();
            nr = NR;
            nc = NC;
            a = new int[nr, nc];
            for (int i = 0; i < nr; i++)
                for (int j = 0; j < nc; j++)
                    a[i, j] = rnd.Next(max + 1);
        }

        // конструктор с генератором случайных чисел от min до max
        public ArrayInt2(int NR, int NC, int min, int max)
        {
            Random rnd = new Random();
            nr = NR;
            nc = NC;
            a = new int[nr, nc];
            for (int i = 0; i < nr; i++)
                for (int j = 0; j < nc; j++)
                    a[i, j] = rnd.Next(min, max + 1);
        }

        // Вывод элементов массива
        public void ArrayInt_Out(string info)
        {
            Console.WriteLine(info);
            for (int i = 0; i < nr; i++)
            {
                for (int j = 0; j < nc; j++)
                    Console.Write(a[i, j].ToString() + "\t");
                Console.WriteLine();
            }
        }

        // Поиск минимального элемента (min) и его позиции (kr,kc)
        public int Min_Array(out int kr, out int kc)
        {
            int min = a[0, 0];
            kr = 0;
            kc = 0;
            for (int i = 0; i < nr; i++)
                for (int j = 0; j < nc; j++)
                    if (a[i, j] < min)
                    {
                        min = a[i, j];
                        kr = i;
                        kc = j;
                    }
            return min;
        }

        // Поиск максимального элемента (max) и его номера (k)
        public int Max_Array(out int kr, out int kc)
        {
            int max = a[0, 0];
            kr = 0;
            kc = 0;
            for (int i = 0; i < nr; i++)
                for (int j = 0; j < nc; j++)
                    if (a[i, j] > max)
                    {
                        max = a[i, j];
                        kr = i;
                        kc = j;
                    }
            return max;
        }

        // Заменить a[kr, kc] на заданный elem (нумерация с 0)
        public void Set_Element(int kr, int kc, int elem)
        {
            if (kr >= 0 && kr < nr && kc >= 0 && kc < nc)
                a[kr, kc] = elem;
        }

        // Извлечь (kr,kc)-й элемент массива (нумерация с 0) 
        public int Get_Element(int kr, int kc)
        {
            if (kr >= 0 && kr < nr && kc >= 0 && kc < nc)
                return a[kr, kc];
            else
                return Int32.MinValue;
        }

    }
}

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

4 5
2 3 4 5 6 
1 3 5 7 9
8 6 4 2 0
9 7 5 3 2

где первая строка задает число строк и столбцов массива, а далее в каждой строке через один пробел записываются элементы массива по строкам. Присвойте файлу имя, например, M2.txt, разместите его в папке с программой (exe-файлом). Тогда при запросе имени файла Вам будет достаточно указать его имя без расширения - M2.
Для примера также выполним перегрузку метода Get_Element(int kr, kc). Тогда получим класс ArrayIntTwo, как дочерний класс от ArrayInt2:

class ArrayIntTwo : ArrayInt2
    {
        // конструкторы без изменений содержимого.
        // могут быть перегружены!
        public ArrayIntTwo(int nr, int nc) : base(nr, nc) { }
        public ArrayIntTwo(int nr, int nc, int max) : base(nr, nc, max) { }
        public ArrayIntTwo(int nr, int nc, int min, int max) : base(nr, nc, min, max) { }

        // конструктор на основе пустого конструктора без параметров в родительском классе 
        // Ввод элементов массива из текстового файла - дополнение
        public ArrayIntTwo(string info) : base()
        {
            Console.WriteLine(info);
            Console.Write("Задайте имя текстового файла данных без расширения, например, M2: ");
            string file_name = Console.ReadLine() + ".txt";
            // проверка, существует ли выбранный файл
            FileInfo fi = new FileInfo(file_name);
            while (!fi.Exists)
            {
                Console.Write("Задайте снова имя файла данных без расширения: ");
                file_name = Console.ReadLine() + ".txt";
                fi = new FileInfo(file_name);
            }
            StreamReader sr; // поток для чтения
            try
            {
                // Чтение чисел из файла без ошибок
                // связывание с файлом, кодировка символов Юникода
                sr = new StreamReader(file_name, UTF8Encoding.Default);
                // чтение 0-й строки (длина массива)
                string t = sr.ReadLine();
                int k = t.IndexOf(" ");
                nr = Convert.ToInt32(t.Substring(0, k));
                t = t.Remove(0, k + 1);
                nc = Convert.ToInt32(t.Substring(0, k));
                a = new int[nr,nc];
                int i = 0; // счетчик строк
                t = sr.ReadLine(); // чтение строк  
                // чтение из файла чисел по строке в массив
                while ((t != null) && (i <= nr))
                {                        
                    k = t.IndexOf(" ");            
                    a[i,0]= Convert.ToInt32(t.Substring(0, k));
                    for (int j = 1; j < nc; j++)
                    {
                        t = t.Remove(0, k + 1);
                        a[i, j] = Convert.ToInt32(t.Substring(0, k));
                        k = t.IndexOf(" ");
                    }
                    i++;
                    t = sr.ReadLine(); // чтение строк  
                }
                // закрытие файла для чтения
                sr.Close();
            }
            catch (Exception ex) // на случай ошибок
            {
                Console.WriteLine("ОШИБКА: " + ex.Message);
            }
        }

        // Для иллюстрации перегрузки метода добавлена только печать строки
        public override int Get_Element(int kr, int kc)
        {
            Console.WriteLine("Перегруженный метод Get_Element()");
            return base.Get_Element(kr, kc);
        }
    }
}

Для тестирования класса напишем в Program.cs:

// Тестирование класса ArrayIntTwo
using System;
namespace ArrayIntTwo
{
    class Program
    {
        static void Main(string[] args)
        {
            ArrayIntTwo X = new ArrayIntTwo(5, 6, 50, 90);
            X.ArrayInt_Out("Исходные данные:");
            int min = X.Min_Array(out int kr1, out int kc1);
            Console.WriteLine("минимум = {0}, индексы = ({1},{2}).", min, kr1, kc1);
            X = new ArrayIntTwo("Ввод из файла");
            X.ArrayInt_Out("Исходные данные из файла:");
            int k = X.Get_Element(1, 2);
            Console.WriteLine("k= " + k);
        }
    }
}

В результате получим:

Исходные данные:
87      88      54      84      74      68
69      69      90      59      72      83
70      63      87      76      88      69
64      53      86      50      84      83
78      67      66      61      90      83
минимум = 50, индексы = (3,3).
Ввод из файла
Задайте имя текстового файла данных без расширения, например, M2: b
Задайте снова имя файла данных без расширения: M2
Исходные данные из файла:
2       3       4       5       6
1       3       5       7       9
8       6       4       2       0
9       7       5       3       2
Перегруженный метод Get_Element()
k= 5

Пример аналогичен примеру, где создается класс для работы с одномерным массивом ArrayIntOne.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Пролистать наверх