Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.

Предоплата всего

Подписываем
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Предоплата всего
Подписываем
Теоретический материал
Вставка и удаление элементов в массивах
При объявлении массива мы определяем его максимальную размерность, которая в дальнейшем изменена быть не может. Однако с помощью вспомогательной переменной можно контролировать текущее количество элементов, которое не может быть больше максимального.
Замечание. В пространстве имен 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);
}
}
Задания.
Рассмотрим модификацию предыдущей программы, для случая, когда используется ступенчатый массив.
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][];
for (int i = 0; i < n; ++i)
{
a[i]=new int[m];
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 k)
{
for (int i = k; i < n-1; ++i)//производим сдвиг ссылок
a[i] = a[i+1];
--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, k);
Console.WriteLine("Измененный массив:");
Print(myArray, n, m);
}
}
}
Вернемся к массиву, определенному в самом первом примере. И подумаем теперь, что значит добавить элемент в одномерный массив в позицию с номером k? В этом случае все элементы, начиная с k-ого, должны быть сдвинуты вправо на одну позицию. Однако сдвиг нужно начинать с конца, т.е. на первом шаге на n-е место поставить n-1-ый элемент, потом на n-1-ое место поставить n-2-й элемент, …, наконец, на k+1 место вставить k-й элемент. Таким образом, копия k-го элемента будет на k+1-м месте и на k-е место можно поставить новый элемент. Затем необходимо увеличить текущее количество элементов на 1.
Рассмотрим массив из примера 1 и в качестве k зададим значение равное 3. В этом случае массив будет выглядеть следующим образом:
k=3 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
а |
0 |
1 |
4 |
9 |
9 |
16 |
0 |
0 |
0 |
0 |
Теперь в позицию с номером 3 можно поместить новое значение. А текущее количество элементов в массиве становится равным 6. Подумайте, почему сдвиг нужно выполнять с конца массива, а не с начала, как мы это делали в случае удаления элемента из массива.
Рассмотрим программную реализацию данного алгоритма:
using System;
namespace ConsoleApplication
{
class Class
{
static int [] Input (out int n)
{
Console.WriteLine("введите размерность массива");
n=int.Parse(Console.ReadLine());
int []a=new int[2*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 AddArray(int[] a, ref int n, int m)
{
for (int i = n; i >= m; --i)
a[i] = a[i-1];
++n;
Console.WriteLine("Введите значение нового элемента");
a[m]=int.Parse(Console.ReadLine());
}
static void Main()
{
int n;
int[] myArray=Input(out n);
Console.WriteLine("Исходный массив:");
Print(myArray, n);
Console.WriteLine("Введите номер элемента для вставки:");
int m=int.Parse(Console.ReadLine());
AddArray(myArray, ref n,m);
Console.WriteLine("Измененный массив:");
Print(myArray, n);
}
}
}
Теперь рассмотрим добавление строки в двумерный массив. Для этого все строки после строки с номером k передвигаем на 1 строку вниз. Затем увеличиваем количество строк на 1. После этого копия строки с номером k будет находиться в столбце с номером k+1. И, следовательно, 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[2*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 AddArray(int[,] a, ref int n, int m, int k)
{
for (int i = n; i >=k; --i)
for (int j = 0; j < m; ++j)
a[i+1, j] = a[i, j];
++n;
Console.WriteLine("Введите элементы новой строки");
for (int j=0; j<m;++j)
{
Console.Write("a[{0},{1}]=", k, j);
a[k, j]=int.Parse(Console.ReadLine());
}
}
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());
AddArray(myArray, ref n, m, k);
Console.WriteLine("Измененный массив:");
Print(myArray, n, m);
}
}
}
Задания.
Рассмотрим модификацию предыдущей программы для случая, когда используется ступенчатый массив.
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[2*n][];
for (int i = 0; i < n; ++i)
{
a[i]=new int [m];
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 AddArray(int[][] a, ref int n, int m, int k)
{
for (int i = n; i >=k; --i)//выполняем сдвиг ссылок
a[i+1] = a[i];
++n;
a[k]=new int[m]; //создаем новую строку
Console.WriteLine("Введите элементы новой строки");
for (int j=0; j<m;++j)
{
Console.Write("a[{0}][{1}]=", k, j);
a[k][j]=int.Parse(Console.ReadLine());
}
}
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());
AddArray(myArray, ref n, m, k);
Console.WriteLine("Измененный массив:");
Print(myArray, n, m);
}
}
}
Практические задания
I. В одномерном массиве, элементы которого целые числа, произвести следующие действия:
II. В двумерном массиве, элементы которого целые числа, произвести следующие действия:
PAGE 1