C#. Разработка обобщенного класса, который содержит средства реализации линейного поиска элемента в массиве




Разработка обобщенного класса, который содержит средства реализации линейного поиска элемента в массиве

В данной теме демонстрируется пошаговый процесс разработки класса LSearch<T>, который содержит ряд методов реализующих линейный поиск элемента (ключа) в одномерном массиве элементов, имеющих тип T. Пройдя все пункты данной темы можно получить опыт по разработке классов на язык C# и изучить основы объектно-ориентированного программирования.


Содержание


Поиск на других ресурсах:

Условие задачи

Используя средства языка C# разработать класс LSearch<T>, содержащий методы, которые осуществляют поиск заданного ключа в одномерном массиве. В классе реализовать:

  • внутренние переменные для сохранения данных;
  • конструкторы и методы доступа к внутренним данным;
  • метод, определяющий наличие элемента в массиве;
  • метод, определяющий количество вхождений заданного элемента в массиве;
  • метод, который возвращает массив номеров позиций вхождения заданного элемента в массиве.

 

Выполнение

1. Создание приложения типа Console Application. Структура проекта

Начальный код модуля, который включает классы LSearch<T> и Program следующий

using static System.Console;

namespace ConsoleApp1
{
  // Класс, обрабатывающий обобщенный тип T
  class LSearch<T>
  {

  }

  class Program
  {
    static void Main(string[] args)
    {
    }
  }
}

 

2. Разработка обобщенного класса LSearch<T>
2.1. Внутренние переменные класса

Линейный поиск реализуется в одномерном массиве. Поэтому, в класс LSearch<T> включается одномерный массив типа T

...

class LSearch<T>
{
  // Внутренние переменные класса
  private T[] A; // Одномерный массив
}

...

 

2.2. Конструкторы класса

В тело класса LSearch<T> вводятся два конструктора:

  • конструктор без параметров LSearch() – инициализирует массив значением null;
  • конструктор с параметром LSearch(T[]) – инициализирует внутренний массив A значениями элементов другого массива. Для выделения памяти и копирования данных в массив A используется метод Clone(), который можно использовать для всех массивов.
// Конструкторы класса.
// Конструктор без параметров
public LSearch()
{
  A = null;
}

// Конструктор, который получает входящим массив элементов типа T
public LSearch(T[] _A)
{
  // Использовать метод Clone()
  A = (T[])_A.Clone(); // скопировать массив
}

 

2.3. Методы доступа к внутреннему массиву

Для доступа к массиву A экземпляра класса LSearch<T> реализованы следующие методы

// Методы доступа к массиву
// Получить ссылку на весь массив
public T[] Get()
{
  return A;
}

// Установить новый массив
public void Set(T[] _A)
{
  A = (T[])_A.Clone();
}

 

2.4. Методы реализации линейного поиска
2.4.1. Метод IsItem(). Определение наличия заданного элемента в массиве

Метод IsItem() определяет, есть ли вообще элемент в массиве. Метод имеет две перегруженных реализации. Первая реализация осуществляет поиск ключа (элемента) во внешнем массиве, который передается в метод входящим параметром. Вторая реализация использует внутренний массив A.

// Методы, которые реализуют линейный поиск
// Определение наличия заданного элемента в массиве
public bool IsItem(T[] A, T key)
{
  for (int i = 0; i < A.Length; i++)
    if (A[i].Equals(key)) // проверка, равны ли значения объектов
      return true;
  return false;
}

// Перегруженный вариант метода IsItem, в котором обрабатывается внутренний массив.
public bool IsItem(T key)
{
  return IsItem(this.A, key);
}

 

2.4.2. Метод GetNOccurences(). Определение количества вхождений заданного элемента в массиве

Метод GetNOccurences() возвращает количество вхождений заданного элемента в массиве. Метод выполняет последовательное сканирование массива от начала до конца и сравнивает входной ключ (элемент) key с каждым элементом массива. Для сравнения используется метод Equals() класса System.Object.

// Определение количества вхождений элемента в массиве
// Реализация метода для любого внешнего массива
public int GetNOccurences(T[] A, T key)
{
  int k = 0;
  for (int i = 0; i < A.Length; i++)
    if (A[i].Equals(key))
      k++;
  return k;
}

// Реализация метода для внутреннего массива
public int GetNOccurences(T key)
{
  return GetNOccurences(this.A, key);
}

 

2.4.3. Метод GetPositions(). Получить массив позиций вхождения заданного элемента в массиве

С помощью перегруженного метода GetPositions() можно получить массив, который содержит номера позиций в которых размещается заданный ключ (элемент). В методе GetPositions() используется метод CopyTo() для копирования одного массива в другой.

// Получить массив позиций вхождения элемента в массиве
public int[] GetPositions(T[] A, T key)
{
  int[] AP = new int[0]; // вначале в массиве 0 элементов
  int[] AP2; // вспомогательный массив

  for (int i = 0; i < A.Length; i++)
  {
    if (A[i].Equals(key))
    {
      // Выделить память для нового массива на 1 элемент больше
      try
      {
        AP2 = new int[AP.Length + 1];

        // Скопировать AP => AP2 - использовать метод CopyTo()
        AP.CopyTo(AP2, 0);

        // Добавить последний элемент
        AP2[AP.Length] = i;

        // Перенаправить ссылку
        AP = AP2;
      }
      catch (Exception e)
      {
        WriteLine(e.Message);
      }
    }
  }

  return AP;
}

// Перегруженная версия метода GetPositions()
public int[] GetPositions(T key)
{
  return GetPositions(this.A, key);
}

 

2.5. Метод вывода внутреннего массива

С целью тестирования в класс LSearch<T> введен метод Print() печати внутреннего массива A на экран.

// Метод вывода массива на экран
public void Print(string comment)
{
  WriteLine(comment);
  for (int i = 0; i < A.Length; i++)
    Write("{0}   ", A[i]);
  WriteLine();
}

 

2.6. Сокращенный текст класса LSearch<T>

Сокращенный вид класса LSearch<T> следующий

// Разработка обобщенного класса, который содержит средства для реализации линейного поиска.
// Класс обрабатывает обобщенный тип T
class LSearch<T>
{
  // Внутренние переменные класса
  private T[] A; // Одномерный массив

  // Конструкторы класса.
  // Конструктор без параметров
  public LSearch()
  {
    ...
  }

  // Конструктор, который получает входящим массив элементов типа T
  public LSearch(T[] _A)
  {
    ...
  }

  // Методы доступа к массиву
  // Получить ссылку на весь массив
  public T[] Get()
  {
    ...
  }

  // Установить новый массив
  public void Set(T[] _A)
  {
    ...
  }

  // Методы, которые реализуют линейный поиск
  // Определение наличия заданного элемента в массиве
  public bool IsItem(T[] A, T key)
  {
    ...
  }

  // Перегруженный вариант метода IsItem, в котором обрабатывается внутренний массив.
  public bool IsItem(T key)
  {
    ...
  }

  // Определение количества вхождений элемента в массиве
  // Реализация метода для любого внешнего массива
  public int GetNOccurences(T[] A, T key)
  {
    ...
  }

  // Реализация метода для внутреннего массива
  public int GetNOccurences(T key)
  {
    ...
  }

  // Получить массив позиций вхождения элемента в массиве
  public int[] GetPositions(T[] A, T key)
  {
    ...
  }

  // Перегруженная версия метода GetPositions()
  public int[] GetPositions(T key)
  {
    ...
  }

  // Метод вывода массива на экран
  public void Print(string comment)
  {
    ...
  }
}

 

3. Тестирование работы класса LSearch<T>. Метод main()

Работа класса тестируется в методе main(), который размещен в классе Program.

class Program
{
  static void Main(string[] args)
  {
    // Тестирование класса LSearch<T>
    int[] AI = { 5, 8, 9, -1, 4 };

    // Создать экземпляр класса LSearch<int> с указанным массивом AI
    LSearch<int> L1 = new LSearch<int>(AI);

    // Определить, есть ли элемент 8. Метод IsItem()
    if (L1.IsItem(8))
      WriteLine("Item 8 is in array AI");
    else
      WriteLine("Item 8 is not in array AI");

    // Тестирование метода GetNOccurences()
    char[] AC = { 'a', 'b', 'f', 'a', 'a', 'c', 'd', 'i', 'f' };
    LSearch<char> L2 = new LSearch<char>(AC);
    int n = L2.GetNOccurences('a');
    WriteLine("n = {0}", n); // n = 3

    // Тестирование метода GetPositions()
    bool[] AB = { true, true, false, false, true, false, true, true }; // массив
    LSearch<bool> L3 = new LSearch<bool>(); // вызывается конструктор без параметров
    L3.Set(AB); // Метод Set() - установить новый массив
    int[] Positions = L3.GetPositions(true);

    // Вывести позиции значения true в массиве AB
    for (int i = 0; i < Positions.Length; i++)
    {
      Write("{0}   ", Positions[i]);
    }
    WriteLine();
    ReadLine();
  }
}

После запуска на выполнение программа выдаст следующий результат

Item 8 is in array AI
n = 3
0 1 4 6 7

 


Связанные темы