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

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

Решение

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

Исходный класс — ArrayInt1

using System;
namespace ArrayIntOne
{
    class ArrayInt1
    {
        protected int n;    // длина массива
        protected int[] a;  // массив целых чисел

        // пустой конструктор - нужен для дочернего класса
        public ArrayInt1() { }

        // конструктор целочисленного массива длиной N. Элементы массива имеют значения по умолчанию
        public ArrayInt1(int N)
        {
            n = N;
            a = new int[n];
        }
 
        // конструктор с генератором случайных чисел от 0 до max
        public ArrayInt1(int N, int max)
        {
            Random rnd = new Random();
            n = N;
            a = new int[n];
            for (int i = 0; i < n; i++)
                a[i] = rnd.Next(max + 1);
        }

        // конструктор с генератором случайных чисел от min до max
        public ArrayInt1(int N, int min, int max)
        {
            Random rnd = new Random();
            n = N;
            a = new int[n];
            for (int i = 0; i < n; i++) a[i] = rnd.Next(min, max + 1); } // Вывод элементов массива с контролем их наличия public virtual void ArrayInt_Out(string info) { Console.WriteLine(info); if (!(a == null)) // число элементов > 0
            {
                foreach (int e in a)
                    Console.Write(e.ToString() + "\t");
                Console.WriteLine();
            }
            else                // число элементов = 0
                Console.WriteLine("Нет элементов " + info);
        }

        // Поиск минимального элемента (min) и его номера (k)
        public virtual int N_min_Array(out int min)
        {
            min = a[0];
            int k = 0;
            for (int i = 1; i < n; i++)
                if (a[i] < min)
                {
                    min = a[i];
                    k = i;
                }
            return k;
        }

        // Поиск максимального элемента (max) и его номера (k)
        public virtual int N_max_Array(out int max)
        {
            max = a[0];
            int k = 0;
            for (int i = 1; i < n; i++) if (a[i] > max)
                {
                    max = a[i];
                    k = i;
                }
            return k;
        }

        // Изменить a[k] на заданный elem (нумерация с 0)
        public virtual void Set_Element(int k, int elem)
        {
            if (k >= 0 && k < n) a[k] = elem; } // Извлечь k-й элемент массива (нумерация с 0) public virtual int Get_Element(int k) { if (k >= 0 && k < n)
                return a[k];
            else
                return Int32.MinValue;
        }

        // Пузырьковая сортировка по возрастанию(U)/убыванию(D)/без нее.
        public virtual void BubbleSort(char d)
        {
            int temp;
            switch (d)
            {
                case 'U':   // по возрастанию
                    for (int i = 0; i < n; i++) for (int j = n - 1; j > i; j--)
                            if (a[j - 1] > a[j])
                            {
                                temp = a[j];
                                a[j] = a[j - 1];
                                a[j - 1] = temp;
                            }
                    break;
                case 'D':   // по убыванию
                    for (int i = 0; i < n; i++) for (int j = n - 1; j > i; j--)
                            if (a[j - 1] < a[j])
                            {
                                temp = a[j];
                                a[j] = a[j - 1];
                                a[j - 1] = temp;
                            }
                    break;
                default:    // без сортировки
                    break;
            }
        }
    }
}

3. Предположим, что нам нужно изменить или что-либо добавить в этот класс. Но им уже пользуются в других проектах, поэтому эти изменения сделаем в дочернем классе, который назовем ArrayIntOne.Три конструктора оставим без изменений, добавим конструктор для чтения из текстового файла.
Пусть файл данных имеет вид:
7
2
4
1
7
6
5
8
где первое число задает количество элементов массива, а далее в каждой строке по одному записываются эти элементы. Присвойте файлу имя, например, M1.txt, разместите его в папке с программой (exe-файлом). Тогда при запросе имени файла Вам будет достаточно указать его имя без расширения — M1.
Для примера также выполним перегрузку метода Get_Element(int k). Тогда получим класс ArrayIntOne, как дочерний класс от ArrayInt1:

Наследование класса — ArrayIntOne

using System;
using System.IO;
using System.Text;
namespace ArrayIntOne
{
    class ArrayIntOne : ArrayInt1
    {
        public delegate bool IsEqual(int x);    // делегат от int x -> bool        
        public int Length   // свойство "Число элементов массива"
        {
            get { return n; }
        }
        // конструкторы без изменений содержимого
        // могут быть перегружены
        public ArrayIntOne(int n) : base(n) { }
        public ArrayIntOne(int n, int max) : base(n, max) { }
        public ArrayIntOne(int n, int min, int max) : base(n, min, max) { }
        // конструктор для ввода данных из текстового файла
        public ArrayIntOne(string info) : base()
        {
            Console.WriteLine(info);
            Console.Write("Задайте имя текстового файла данных без расширения: ");
            string file_name = Console.ReadLine() + ".txt";
            StreamReader sr; // поток для чтения
            try
            {
                // Чтение чисел из файла без ошибок
                // связывание с файлом, кодировка символов Юникода
                sr = new StreamReader(file_name, UTF8Encoding.Default);
                // чтение 0-й строки (длина массива)
                string t = sr.ReadLine();
                n = Convert.ToInt32(t);
                a = new int[n];
                int i = 0; // счетчик строк
                // чтение из файла чисел по строке в массив
                while ((t != null) && (i < n))
                {
                    t = sr.ReadLine(); // чтение строк                                 
                    a[i] = Convert.ToInt32(t);
                    i++;
                }
                // закрытие файла для чтения
                sr.Close();
            }
            catch (Exception ex) // на случай ошибок
            {
                Console.WriteLine("ОШИБКА: " + ex.Message);
            }
        }
        // конструктор для ввода массива с клавиатуры (если строковый параметр имеет значение "keyboard") - Автор Эд.
        // или из строки, в которой целые числа (элементы массива) разделены пробелами.
        // если в строке чисел меньше, чем длина массива, последние элементы массива получают значение по умолчанию
        // если в строке чисел больше, чем длина массива, последние числа строки не учитываются
        // если k-й элемент строки нельзя преобразовать в целое число, k-й элемент массива получает значение по умолчанию
        public ArrayIntOne(int N, string s)
        {
            n = N;
            a = new int[n];
            if (s == "keyboard")
            {
                Console.WriteLine("Введите {0} элементов целочисленного массива", n);
                for (int i = 0; i < n; i++)
                {
                    Console.Write("a[{0}]: ", i);
                    a[i] = Convert.ToInt32(Console.ReadLine());
                }
            }
            else
            {
                string[] numbers = s.Split(' ', StringSplitOptions.RemoveEmptyEntries);
                for (int i = 0; i < n; i++)
                {
                    if (i < numbers.Length && Int32.TryParse(numbers[i], out int b))
                        a[i] = b;
                }
            }
        }

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

        // Суммирование элементов массива
        public int Sum()
        {
            int sum = 0;
            foreach (int e in a)
                sum += e;
            return sum;
        }
        // метод находит все элементы массива удовлетворяющие условию, заданному делегатом (лямбда-выражением)
        // и возвращает новый экземпляр класса (массив, состоящий из этих элементов) - автор Эд.
        public ArrayIntOne Find_All(IsEqual fnc)
        {
            int b = 0;  // число элементов, удовлетворяющих условию           
            foreach (int i in a)
                if (fnc(i))
                    b += 1;
            ArrayIntOne a1 = new ArrayIntOne(b); // инициализация нового массива
            // заполнение нового массива по условию, задаваемому предикатом
            b = 0;
            for (int i = 0; i < n; i++)
                if (fnc(a[i]))
                {
                    a1.Set_Element(b, a[i]);
                    b++;
                }
            return a1;
        }
    }
}

Замечу, что для чтения файла понадобились директивы

using System.IO;
using System.Text;

4. В решениях задач по основам C# вы часто использовали различные алгоритмы контроля ввода целых чисел. Ранее был написан класс Restricted Integer Number (RIN) — «Ограниченное целое число», который удобно использовать в нашей тестовой программе:

Класс RIN — ограниченное целое число

class RIN
{
   int min = 0;    // нижняя граница
   int max = 100;  // верхняя граница
   public string info = "число"; // имя параметра
   public bool n_bool; // успешность преобразования

   // Ограниченное число: поле n и свойство N
   int n;
   public int N    // свойство
   {
      get { return n; }
      set
      {
         if (value < min) { n = min; n_bool = false; } else if (value > max)
         {
            n = max;
            n_bool = false;
         }
         else
         {
            n = value;
            n_bool = true;
         }
      }
   }

   // конструктор
   public RIN(string n_st, int n_min, int n_max, int n_def, string n_info)
   {
      min = n_min;
      max = n_max;
      info = n_info;
      n_bool = true;
      try
         {
            N = Convert.ToInt32(n_st);
            if (!n_bool)
            {
               info = "Ошибка ввода параметра << " + info + " >>. Число вне диапазона. Автоматически присваивается нижняя/верхняя граница. Для изменения введите целое число от " + min.ToString() + " до " + max.ToString();
            }
         }
         catch
         {
            info = "Ошибка ввода параметра << " + info + " >>. Введите целое число от " + min.ToString() + " до " + max.ToString() + ". По умолчанию параметр =  " + n_def.ToString(); ;
            n = n_def;
            n_bool = false;
         }
      }
   }   // end class RIN

5. Для тестирования нового класса в Program.cs напишем следующий код:

Класс Program

using System;
namespace ArrayIntOne
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("Введите целое число: ");
            string number = Console.ReadLine();
            RIN rin = new RIN(number, 1, 1000, 4, "число");
            int n = rin.N;  // заданная длина массива

            // Дополнительная информация о вводе числа
            Console.WriteLine("Ваше число: {0}", n);
            if (!rin.n_bool)
                Console.WriteLine(rin.info);

            ArrayIntOne X1 = new ArrayIntOne(n);
            X1.ArrayInt_Out("Исходные данные 1:");

            ArrayIntOne X0 = new ArrayIntOne("arrayOne");
            X0.ArrayInt_Out("Исходные данные из файла:");

            ArrayIntOne X2 = new ArrayIntOne(8, 30);
            X2.ArrayInt_Out("Исходные данные 2:");

            ArrayIntOne X = new ArrayIntOne(10, 40, 60);
            X.ArrayInt_Out("Исходные данные:");

            int k1 = X.N_min_Array(out int min);
            Console.WriteLine("номер минимального элемента {0}, значение = {1}.", k1, min);

            int k2 = X.N_max_Array(out int max);
            Console.WriteLine("номер максимального элемента {0}, значение = {1}.", k2, max);

            X.BubbleSort('U');
            X.ArrayInt_Out("Отсортированный массив по возрастанию ('Up'):");

            int k = 6;
            X.Set_Element(k, 80);
            X.ArrayInt_Out("С изменением массив:");

            k = 5;
            Console.WriteLine("номер элемента {0}, значение = {1}.", k, X.Get_Element(k));

            X.BubbleSort('D');
            X.ArrayInt_Out("Отсортированный массив по убыванию ('Down'):");
          
            // проверка конструкторов c сигнатурой (int, string)

            ArrayIntOne X = new ArrayInt1(4, "keyboard");
            X.ArrayInt_Out("массив с клавиатуры:");

            X = new ArrayIntOne(7);
            X.ArrayInt_Out("массив из нулей:");

            X = new ArrayIntOne(4, "2 3 4 5");
            X.ArrayInt_Out("массив как есть:");

            X = new ArrayIntOne(4, "2 3.5 4 5");
            X.ArrayInt_Out("массив с ошибкой в строке:");

            X = new ArrayIntOne(4, "2 4 5");
            X.ArrayInt_Out("массив с нулем в конце");

            X = new ArrayIntOne(4, "20 40 50 60 70");
            X.ArrayInt_Out("массив заданной длины:");    
       
            // проверка свойства 
            Console.WriteLine("число элементов массива = " + X.Length);
 
// Дан массив. Задание 1. Найти: сумму элементов массива, значение которых не превышает 20;
            Console.WriteLine("Дан массив. Найти сумму элементов массива, значение которых не превышает 20;");
            // вызов конструктора c сигнатурой (int, int)
            X = new ArrayInt1(20, 40);
            X.ArrayInt_Out("Массив из 20 целых чисел (0 <= a <= 40):"); 
            ArrayInt1 Y; // новый массив как объект 
            Y = X.Find_All(x => x <= 20); // с лямбда-выражением для метода Find_All() 
            Y.ArrayInt_Out("Эти элементы не больше 20:"); 
            Console.WriteLine("Их сумма = " + Y.Sum()); 

// Задание 2. Дан массив. Найти: сумму элементов массива, больших числа a. 
            Console.WriteLine("Найти сумму элементов массива, больших числа a."); 
            int a = Vvod_Chisla_Int("a"); 
            Y = X.Find_All(x => x > a); // с лямбда-выражением для метода Find_All()
            Y.ArrayInt_Out("Эти элементы больше " + a + ":");
            Console.WriteLine("Их сумма = " + Y.Sum());
            Console.ReadKey();
        }
    }
}

Тогда может быть получен

Результат тестирования

Введите целое число: 8
Ваше число: 8
Исходные данные 1:
0       0       0       0       0       0       0       0
arrayOne
Задайте имя текстового файла данных без расширения: M1
Исходные данные из файла:
2       4       1       7       6       5       8
Исходные данные 2:
4       5       25      9       24      24      12      21
Исходные данные:
60      48      47      48      55      56      60      43      54      44
номер минимального элемента 7, значение = 43.
номер максимального элемента 0, значение = 60.
Отсортированный массив по возрастанию ('Up'):
43      44      47      48      48      54      55      56      60      60
С изменением массив:
43      44      47      48      48      54      80      56      60      60
Перегруженный метод Get_Element()
номер элемента 5, значение = 54.
Отсортированный массив по убыванию ('Down'):
80      60      60      56      54      48      48      47      44      43
Введите 4 элементов целочисленного массива
a[0]: 4
a[1]: 5
a[2]: 1
a[3]: 78
массив с клавиатуры:
4       5       1       78
массив из нулей:
0       0       0       0       0       0       0
массив как есть:
2       3       4       5
массив с ошибкой в строке:
2       0       4       5
массив с нулем в конце
2       4       5       0
массив заданной длины:
20      40      50      60
число элементов массива = 4
Дан массив. Найти:
а) сумму элементов массива, значение которых не превышает 20;
Массив из 20 целых чисел (0 <= a <= 40):
20      26      37      32      0       36      3       20      30      6       21      20      4       22      7       12      17      25      2       13
Эти элементы не больше 20:
20      0       3       20      6       20      4       7       12      17      2       13
Их сумма = 124
б) сумму элементов массива, больших числа a.
Эти элементы больше 20:
26      37      32      36      30      21      22      25
Их сумма = 229

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

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

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

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