Опубликован: 19.02.2009 | Доступ: свободный | Студентов: 3057 / 787 | Оценка: 4.35 / 4.11 | Длительность: 16:28:00
ISBN: 978-5-94774-401-9
Лекция 8:

Массивы

< Лекция 7 || Лекция 8: 123456 || Лекция 9 >

Самостоятельная работа

Теоретический материал

Вставка и удаление элементов в массивах

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

Замечание. В пространстве имен System.Collection реализована коллекция ArrayList - массив, динамически изменяющий свой размер. Мы будем рассматривать его позже.

Пример. Рассмотрим фрагмент программы:

int []a=new int [10];
int n=5;
for (int i=0; i<5;i++) a[i]:=i*i;

В этом случае массив можно представить следующим образом:

n=5 0 1 2 3 4 5 6 7 8 9
а 0 1 4 9 16 0 0 0 0 0

Так как во время описания был определен массив из 10 элементов, а заполнено только первые 5, то оставшиеся элементы будут заполнены нулями.

Что значит удалить из одномерного массива элемент с номером 3? Удаление должно привести к физическому "уничтожению" элемента с номером 3 из массива, при этом общее количество элементов должно быть уменьшено. В этом понимании удаления элемента итоговый массив должен выглядеть следующем образом

0 1 2 4 5 6 7 8 9 недопустимое состояние
а 0 1 4 16 0 0 0 0 0

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

Однако "удаление" можно смоделировать сдвигом элементов влево и уменьшением значения переменной, которая отвечает за текущее количество элементов в массиве, на единицу:

n=4 0 1 2 3 4 5 6 7 8 9
а 0 1 4 16 0 0 0 0 0 0

В общем случае, если мы хотим удалить элемент массива с номером k (всего в массиве n элементов, а последний элемент имеет индекс n-1 ), то нам необходимо произвести сдвиг элементов, начиная с k+1 -го на одну позицию влево. Т.е. на k -ое место поставить k+1 -й элемент, на место k+1 - k+2 -й элемент, …, на место n-2 - n-1 -й элемент. После чего значение n уменьшить на 1. В этом случае размерность массива не изменится, изменится лишь текущее количество элементов, и у нас создастся ощущение, что элемент с номером k удален. Рассмотрим данный алгоритм на примере:

using System;
namespace ConsoleApplication
{
  class Class
  {
    static int [] Input ()
    {
      Console.WriteLine("введите размерность массива");
      int n=int.Parse(Console.ReadLine());
      int []a=new int[n];
      for (int i = 0; i < n; ++i) 
      {
        Console.Write("a[{0}]= ", i);
        a[i]=int.Parse(Console.ReadLine());
      }
      return a;
    }

    static void Print(int[] a, int n) 
    {
      for (int i = 0; i < n; ++i) Console.Write("{0} ", a[i]);
      Console.WriteLine();
    }

    static void DeleteArray(int[] a, ref int n, int m)
    {
      for (int i = m; i < n-1; ++i)
        a[i] = a[i+1];
      --n;
    }

    static void Main()
    {
      int[] myArray=Input();
      int n=myArray.Length;
      Console.WriteLine("Исходный массив:");
      Print(myArray, n);
      Console.WriteLine("Введите номер элемента для удаления:");
      int m=int.Parse(Console.ReadLine());
DeleteArray(myArray, ref n,m);
      Console.WriteLine("Измененный массив:");
      Print(myArray, n);
    }
  }
}
Задание. Подумайте, какие исключительные ситуации могут возникнуть в данной программе и добавьте в нее соответствующие обработки исключительных ситуаций

Рассмотрим теперь операцию удаления в двумерном массиве. Размерность двумерного массива также зафиксирована на этапе объявления массива. Однако при необходимости можно "смоделировать" удаление целой строки в массиве, выполняя сдвиг всех строк, начиная с k -той на единицу вверх. В этом случае размерность массива не изменится, а текущее количество строк будет уменьшено на единицу. В качестве примера удалим из двумерного массива, строку с номером k.

using System;
namespace ConsoleApplication
{
  class Class
  {
    static int [,] Input (out int n, out int m)
    {
      Console.WriteLine("введите размерность массива");
      Console.Write("n = ");
      n=int.Parse(Console.ReadLine());
      Console.Write("m = ");
      m=int.Parse(Console.ReadLine());
      int [,]a=new int[n, m];
      for (int i = 0; i < n; ++i) 
        for (int j = 0; j < m; ++j)
        {
          Console.Write("a[{0},{1}]= ", i, j);
          a[i, j]=int.Parse(Console.ReadLine());
        }
      return a;
    }

    static void Print(int[,] a, int n, int m) 
    {
      for (int i = 0; i < n; ++i,Console.WriteLine() )
        for (int j = 0; j < m; ++j)
          Console.Write("{0,5} ", a[i, j]);
    }

    static void DeleteArray(int[,] a, ref int n, int m, int k)
    {
      for (int i = k; i < n-1; ++i)
        for (int j = 0; j < m; ++j)
          a[i, j] = a[i+1, j];
      --n;
    }

    static void Main()
    {
      int n,m;
      int[,] myArray=Input(out n, out m);
      Console.WriteLine("Исходный массив:");
      Print(myArray, n, m);
      Console.WriteLine("Введите номер строки для удаления:");
      int k=int.Parse(Console.ReadLine());
      DeleteArray(myArray, ref n, m, k);
      Console.WriteLine("Измененный массив:");
      Print(myArray, n, m);
    }
  }
}
Задания.
  1. Подумайте, какие исключительные ситуации могут возникнуть в данной программе и добавьте в нее соответствующие обработки исключительных ситуаций.
  2. Измените программу так, чтобы она удаляла k -тый столбец в двумерном массиве.
< Лекция 7 || Лекция 8: 123456 || Лекция 9 >