Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ПиОА_1 семестр_1 / ПОСОБИЕ_VB.Net

.pdf
Скачиваний:
658
Добавлен:
06.03.2016
Размер:
3.4 Mб
Скачать

свойства Text объекта b вместе с пробелом. Свойство Length класса Array определяет количество элементов в массиве a, который передается в процедуру при вызове.

Для второго варианта. Входными параметрами для данной процедуры являются одномерный массив a (что выводится) и объект класса DataGridView b (куда осуществляется вывод). Оба параметра передаются по значению. В цикле с параметром очередной элемент массива a конвертируется в строку символов и выводится в ячейку j нулевой строки объекта b. Свойство Length класса Array определяет количество элементов в массиве a, который передается в процедуру при вызове. Метод GetUpperBound(0) определяет индекс последнего элемента в массиве a.

Для третьего варианта. Входными параметрами для данной процедуры являются двумерный массив a (что выводится) и объект класса DataGridView b (куда осуществляется вывод). Оба параметра передаются по значению. Во вложенных циклах с параметром очередной элемент массива a конвертируется в строку символов и выводится в ячейку j i-ой строки объекта b. Методы GetLength(0) и GetLength (1) класса Array определяют количество элементов по первому (строки) и второму (столбцы) измерению массива a, который передается в процедуру при вызове. Методы

GetUpperBound(0) и GetUpperBound(1) класса Array опре-

деляют индексы последнего элемента по первому (строки) и второму (столбцы) измерению массива a.

Пояснение к процедуре Button1_Click. В данной процедуре с по-

мощью текстовых окон задаются: левая и правая границы диапазона выборки случайных чисел, размеры одномерного (n) и двумерного массивов (k – строк, m – столбцов). Далее с помощью Redim распределяется память под массивы: одномерного a и двумерного b.

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

48

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

При вызове перегруженной процедуры out_put вывод массивов (одномерного или двумерного) будет осуществляться в объекты класса TextBox или класса DataGridView в зависимости от того, какие фактические параметры будут в нее передаваться.

Интерфейс задачи представлен на рис. 6.7.

Рис. 6.7 Интерфейс задачи 6.1

49

Обработка массивов

Задача 6.2. Для одномерного массива определить:

-сумму элементов одномерного массива;

-количество положительных элементов одномерного массива;

-номер первого минимального элемента одномерного массива.

Фрагменты программного кода:

'вычисление суммы s элементов одномерного массива s = 0

For i As Int32 = 0 to a.GetUpperBound(0) s += a(i)

Next i

'вычисление количества положительных элементов k 'в одномерном массиве

k = 0

For i As Int32 = 0 to a.GetUpperBound(0) If a(i) > 0 Then k += 1

Next i

'определение номера минимального элемента imin 'в одномерном массиве

min = a(0) : imin = 0

For i As Int32 = 0 to a.GetUpperBound(0) If a(i) < min Then

min = a(i) : imin = i

End if Next i

Задача 6.3. Для двумерного массива определить:

-сумму всех элементов;

-сумму элементов каждого столбца;

-количество всех отрицательных элементов;

-местоположение последнего минимального элемента;

-максимальные элементы в каждой строке.

50

Фрагменты программного кода:

'Расчет суммы элементов двумерного массива s = 0

For i As Int32 = 0 to a.GetUpperBound(0) For j As Int32 = 0 to a.GetUpperBound(1)

s += a(i,j)

Next j

Next i

'вывод суммы s

'Расчет суммы столбцов двумерного массива

For j As Int32 = 0 to a.GetUpperBound(1) s = 0

For i As Int32 = 0 to a.GetUpperBound(0) s += a(i,j)

Next i

'вывод суммы s столбца j Next j

'Расчет количества отрицательных элементов в двумерном массиве k = 0

For i As Int32 = 0 to a.GetUpperBound(0) For j As Int32 = 0 to a.GetUpperBound(1)

If a(i,j) < 0 Then k += 1

Next j

Next i

'вывод количества элементов k

'Определение индексов последнего минимального элемента 'в двумерном массиве

min = a(0,0) : imin = 0 : jmin = 0

For i As Int32 = 0 to a.GetUpperBound(0) For j As Int32 = 0 to a.GetUpperBound(1) If a(i,j) <= min Then

min = a(i,j) : imin = i : jmin = j

End if Next j

51

Next i

'вывод номера строки imin и номера столбца jmin минимального элемента

'Определение максимальных элементов каждой строки 'в двумерном массиве

For i As Int32 = 0 To a.GetUpperBound(0) max = a(0,0)

For j As Int32 = 0 To a.GetUpperBound(1) If a(i,j) > max Then max = a(i,j)

Next j

'вывод максимального элемента max i-ой строки

Next i

Типовые задачи обработки квадратных матриц

Для данных задач характерно то, что номера строк и столбцов элементов, расположенных на главной или побочной диагонали связаны определенными соотношениями:

для главной диагонали: i = j

 

0

1

2

3

0

a(0,0)

a(0,1)

a(0,2)

a(0,3)

 

 

 

 

 

 

1

a(1,0)

a(1,1)

a(1,2)

a(1,3)

 

 

 

 

 

2

a(2,0)

a(2,1)

a(2,2)

a(2,3)

 

 

 

 

 

3

a(3,0)

a(3,1)

a(3,2)

a(3,3)

 

 

 

 

 

для побочной диагонали: i = N – 1 – j или j = N - 1 – i

 

0

1

2

3

0

a(0,0)

a(0,1)

a(0,2)

a(0,3)

 

 

 

 

 

 

1

a(1,0)

a(1,1)

a(1,2)

a(1,3)

 

 

 

 

 

2

a(2,0)

a(2,1)

a(2,2)

a(2,3)

 

 

 

 

 

3

a(3,0)

a(3,1)

a(3,2)

a(3,3)

 

 

 

 

 

52

Поэтому, для обработки элементов, расположенных на диагоналях, достаточно одного цикла, а для обработки элементов над или под диагоналями потребуются вложенные циклы.

Причем эту обработку можно выполнить двумя путями:

1.Заложить во внутреннем цикле условие проверки индексов по приведенным формулам (табл. 6.4, 2 столбец);

2.Организовать циклы так, чтобы рассматривать только требуемые элементы (табл. 6.4, 3 столбец).

Таблица 6.4. Соотношение индексов и организация циклов относительно диагоналей в квадратных матрицах

 

Соотношение

Организация циклов

 

индексов

Расположение элементов

(n количество элементов в

(i – номер строки,

 

строках и столбцах)

 

j – номер столбца)

 

 

На главной диагонали

i = j

For i = 0 To n-1

 

 

 

Выше главной диагонали

i < j

For i = 0 To n-1

For j = i To n-1

 

 

 

 

 

Ниже главной диагонали

i > j

For i = 0 To n-1

For j = 0 To i

 

 

 

 

 

На побочной диагонали

j = n - 1 – i

For i = 0 To n-1

 

 

 

Выше побочной

i < n - 1 – j

For i = 0 To n-1

диагонали

For j = 0 To n-1-i

 

 

 

 

Ниже побочной

i > n - 1 – j

For i = 0 To n-1

диагонали

For j = n-1-i To n-1

 

 

 

 

Задача 6.4. Определить сумму элементов, расположенных:

1.на главной и побочной диагонали;

2.на главной диагонали и выше ее;

3.ниже главной диагонали;

4.на побочной диагонали и выше ее;

5.ниже побочной диагонали.

Ниже представлены фрагменты программного кода решения за-

дачи.

53

На главной и побочной диагонали:

Рассматриваемые элементы

Фрагмент программного кода

 

'На главной диагонали

 

sum = 0

: n = a.GetLength(0)

 

For i =

0 to n -

1

 

sum += a(i, i)

 

 

Next i

 

 

 

'На побочной диагонали

 

sum = 0

: n = a.GetLength(0)

 

For i =

0 to n -

1

 

sum += a(i, n -

1- i)

 

Next i

 

 

На главной диагонали и выше ее:

Рассматриваемые

1 вариант (с условием про-

2 вариант (циклы рассмат-

ривают только требуемые

элементы

верки индексов)

элементы)

 

 

 

sum = 0

 

 

n = a.GetLength(0)

sum = 0

 

For i = 0 to n - 1

n = a.GetLength(0)

 

For j = 0 to n - 1

For i = 0 to n - 1

 

 

 

if i < = j then

For j = i to n - 1

 

sum += a(i,j)

sum += a(i,j)

 

 

 

end if

next j

 

 

 

Next j

next i

 

Next i

 

Ниже главной диагонали:

Рассматриваемые

1 вариант (с условием про-

2 вариант (циклы рассмат-

элементы

верки индексов)

ривают только требуемые

элементы)

 

 

 

sum = 0

 

 

n = a.GetLength(0)

sum = 0

 

For i = 0 to n - 1

n = a.GetLength(0)

 

 

 

For j = 0 to n - 1

For i = 1 to n - 1

 

if i > j then

For j = 0 to i - 1

 

 

 

sum += a(i,j)

sum += a(i,j)

 

end if

next j

 

 

 

Next j

next i

 

Next i

 

 

54

 

На побочной диагонали и выше ее:

Рассматриваемые

1 вариант (с условием про-

2 вариант (циклы рассмат-

ривают только требуемые

элементы

верки индексов)

элементы)

 

 

 

sum = 0

 

 

n = a.GetLength(0)

sum = 0

 

For i = 0 to n - 1

n = a.GetLength(0)

 

 

 

For j = 0 to n - 1

For i = 0 to n - 1

 

if i+j < = n-1 then

For j = 0 to n –1-i

 

sum += a(i,j)

sum += a(i,j)

 

end if

Next j

 

Next j

Next i

 

Next i

 

 

 

 

Ниже побочной диагонали:

Рассматриваемые

1 вариант (с условием про-

2 вариант (циклы рассмат-

элементы

верки индексов)

ривают только требуемые

элементы)

 

 

 

sum = 0

sum = 0

 

n = a.GetLength(0)

 

n = a.GetLength(0)

 

For i = 0 to n - 1

 

 

 

For j = 0 to n - 1

For i = 0 to n - 1

 

if i+j > n-1 then

For j = n-i to n–1

 

sum += a(i,j)

sum += a(i,j)

 

end if

Next j

 

Next j

 

Next i

 

Next i

 

 

 

 

 

Модификация массивов

Задача 6.5. Переставить элементы одномерного массива в обратном порядке.

Фрагмент программного кода:

n = a.GetLength(0)

For i As Int32 = 0 To n \ 2 - 1 z = a(i)

a(i) = a(n - i - 1) a(n - i - 1) = z

Next i

55

Пояснение. Цикл выполняется лишь до половины диапазона рассматриваемых элементов, иначе в массиве ничего не изменится. n – количество элементов в массиве. z – переменная (буфер) для временного хранения (рис. 6.8).

Если воспользоваться методом reverse класса array, то приведенный выше код можно заменить одной строкой:

Array.Reverse(a)

Рис. 6.8 Перестановка элементов массива в обратном порядке

Задача 6.6. Переставить в обратном порядке часть массива между элементами с номерами k1 и k2, включая их.

Фрагмент программного кода:

For i As Int32 = 0 To (k2 - k1 + 1) \ 2 - 1 z = a(i + k1)

a(i + k1) = a(k2 - i) a(k2 - i) = z

Next

Если воспользоваться методом reverse класса array, то приведенный выше код можно заменить одной строкой:

Array.Reverse(a, k1, k2 - k1 + 1)

56

Пояснение. Вторым параметром метода указывается индекс начального элемента (k1) с которого начинается изменение, третьим – длина части массива, которую нужно изменить (k2 - k1 + 1).

Задача 6.7. Переставить элементы следующим образом:

a(0), a(11), a(1), a(10), a(2), a(9), a(3), a(8), a(4), a(7), a(5), a(6).

Фрагмент программного кода:

n = a.GetLength(0) ReDim b(n - 1)

j = 0

For i As Int32 = 0 To n - 1 If i Mod 2 = 0 Then

b(i) = a(j) j += 1

Else

b(i) = a(n - j)

End If Next

Пояснение. При решении данной задачи изменяется не сам заданный массив a, а формируется новый массив b той же размерности, в который пересылаются элементы массива a в нужном порядке.

Задача 6.8. Циклически сдвинуть элементы одномерного массива на

одну позицию влево.

Фрагмент программного кода:

n = a.GetLength(0)

For i As Int32 = 0 To n - 2 z = a(i)

a(i) = a(i + 1) a(i + 1) = z

Next i

Пояснение. Цикл выполняется с первого до предпоследнего элемента, n – количество элементов в массиве, z – переменная (буфер) для временного хранения (рис. 6.9). Сдвиг осуществляется влево, элементы массива просматриваются слева направо – с первого до предпоследнего элемента.

57

Рис. 6.9 Циклический сдвиг элементов массива влево

Задача 6.9. Циклически сдвинуть элементы одномерного массива на одну позицию вправо.

Фрагмент программного кода:

n = a.GetLength(0)

For i As Int32 = n - 2 To 0 Step -1 z = a(i + 1)

a(i + 1) = a(i) a(i) = z

Next

Пояснение. Цикл выполняется с предпоследнего элемента до первого. n – количество элементов в массиве.

z – переменная (буфер) для временного хранения (рис. 6.9).

Сдвиг осуществляется вправо, элементы массива просматриваются справа налево – с предпоследнего до первого элемента.

58

Рис. 6.10 Циклический сдвиг элементов массива вправо

Задача 6.10. Удалить из одномерного массива элементы кратные трем.

Интерфейс задачи представлен на рис. 6.11. Программный код:

Public Class Form1

Sub out_put(ByVal a() As Int32, ByVal b As TextBox) b.Text = ""

For i As Int32 = 0 To a.Length - 1 b.Text &= Convert.ToString(a(i)) & " "

Next i

End Sub

Private Sub Button1_Click(...) Handles Button1.Click Dim a() As Int32 = {0, 3, 2, 6, -9, 12, 4, 15, 5, 7} Dim n As Int32 = a.Length

Dim i As Int32 Dim kol As Int32

out_put(a, TextBox1) i = 0 : kol = 0

'Цикл по просмотру элементов массива

While i <= n - 1

If (a(i) Mod 3 <> 0) Or (a(i) = 0) Then

59

i += 1 ' Увеличение параметра цикла, если элемент не кратен 3

Else

For j = i To n - 2 ' Цикл для удаления элемента кратного 3 a(j) = a(j + 1)

Next j

kol += 1 'Увеличение счетчика удаленных элементов

End If

End While 'Конец цикла While

'Изменение размера массива a с сохранением оставшихся элементов

ReDim Preserve a(n - kol - 1) out_put(a, TextBox2)

End Sub

End Class

Пояснение. В данном программном коде переменная n отвечает за количество элементов в массиве a, kol – счетчик количества элементов кратных 3, т.е. удаленных элементов.

Инициализация массива a оператором Redim с использованием ключевого слова Preserve позволяет изменить размер массива и при этом сохранить необходимые элементы, так как в этом случае происходит копирование элементов из существующего массива в новый проинициализированный массив.

Рис. 6.11 Интерфейс задачи 6.10

Задача 6.11. Вставить число k в заданный упорядоченный по возрастанию массив, не нарушая его упорядоченности. Последний элемент массива вытесняется.

Интерфейс задачи представлен на рис. 6.12.

60

Программный код:

Public Class Form1

Sub out_put(ByVal a() As Double, ByVal b As TextBox) b.Text = ""

For i As Int32 = 0 To a.Length - 1

b.Text &= Convert.ToString(a(i)) & " "

Next i

End Sub

Private Sub Button1_Click(...) Handles Button1.Click Dim a() As Double = {-1,2.5,3,5.1,6,7.6,7.8,9,9.5,10} Dim n As Int32 = a.Length

Dim k As Double = Convert.ToDouble(TextBox1.Text)

'Цикл для организации поиска места для вставки out_put(a, TextBox2)

For i As Int32 = 0 To n - 1

If k <= a(i) Then 'Ищется элемент массива, не меньший числа k ', т.е. место вставки

'Если место найдено, то организуется цикл для смещения ' элементов массива на единицу вправо

For j As Int32 = n - 1 To i + 1 Step -1 a(j) = a(j - 1) 'Смещение вправо

Next j

a(i) = k ' Вставка нового значения на освобожденное место

Exit For 'Досрочный выход из внешнего цикла i, если k вставлено

End If

Next i 'Конец внешнего цикла

out_put(a, TextBox3)

End Sub

End Class

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

61

Рис. 6.12 Интерфейс задачи 6.11

Задача 6.12. Вставить число x после всех четных элементов одномерного массива. Все элементы массива сохраняются.

Интерфейс задачи представлен на рис. 6.13. Программный код:

Public Class Form1

Sub out_put(ByVal a() As Int32, ByVal b As TextBox) b.Text = ""

For i As Int32 = 0 To a.Length - 1

b.Text &= Convert.ToString(a(i)) & " "

Next i

End Sub

Private Sub Button1_Click(...) Handles Button1.Click Dim a() As Int32 = {0, 3, 2, 6, -9, 12, 4, 15, 5, 7} Dim n As Int32 = a.Length

Dim i As Int32

Dim

kol As Int32 =

0 'Счетчик количества вставок

Dim x As Int32 = Convert.ToInt32(TextBox1.Text)

out_put(a, TextBox2)

 

ReDim Preserve a(2 * n -

1)

For i = n - 1 To 0

Step -1 'Перебор элементов c конца

If (Math.Abs(a(i)) Mod 2 = 0) _

 

And (a(i) <> 0)

_

 

And (a(i) <> x)

Then

'Если место найдено, то элементы смещаются вправо

For j = n + kol - 1 To i + 1 Step -1 a(j + 1) = a(j)

Next j

62

a(i + 1)

= x 'Вставка числа x

kol += 1

'Счетчик количества вставок увеличивается на 1

End If

 

Next i

 

ReDim Preserve a(n + kol - 1)

'Вывод массива с учетом вставленных элементов out_put(a, TextBox3)

End Sub

End Class

Пояснение. В данном программном коде два раза используется оператор ReDim с ключевым словом Preserve. При первом использовании размер массива увеличивается в два раза (на случай, если все элементы массива четные). При втором использовании размер массива становится равным количеству элементов в старом массиве (n) плюс количество вставленных элементов (kol). При этом элементы массива сохраняются.

Рис. 6.13 Интерфейс задачи 6.12

Задача 6.13. Повернуть двумерный массив:

1.на 180 градусов по часовой стрелке;

2.на 90 градусов по часовой стрелке;

3.на 90 градусов против часовой стрелки;

4.относительно горизонтальной оси;

5.относительно вертикальной оси;

6.относительно главной диагонали (для квадратных матриц)

63

Ниже представлены фрагменты программных кодов данной за-

дачи.

Поворот на 180 градусов по часовой стрелке:

Массив

Массив

Фрагмент программного кода

до поворота

после поворота

 

 

 

n = a.GetLength(0)

 

 

m = a.GetLength(1)

 

 

ReDim b(n - 1, m - 1)

 

 

For i As Int32 = 0 To n - 1

 

 

For j As Int32 = 0 To m - 1

 

 

b(i, j) = a(n-i-1, m-j-1)

 

 

Next j

 

 

Next i

 

 

 

Поворот на 90 градусов по часовой стрелке:

Массив

Массив

Фрагмент программного кода

до поворота

после поворота

 

 

 

n = a.GetLength(0)

 

 

m = a.GetLength(1)

 

 

ReDim b(m - 1, n - 1)

 

 

For i As Int32 = 0 To m - 1

 

 

For j As Int32 = 0 To n - 1

 

 

b(i, j) = a(n - j - 1, i)

 

 

Next j

 

 

Next i

 

 

 

Поворот на 90 градусов против часовой стрелки:

Массив

Массив

Фрагмент программного кода

до поворота

после поворота

 

 

 

n = a.GetLength(0)

 

 

m = a.GetLength(1)

 

 

ReDim b(m - 1, n - 1)

 

 

For i As Int32= 0 To m - 1

 

 

For j As Int32= 0 To n - 1

 

 

b(i, j) = a(j, m - i - 1)

 

 

Next j

 

 

Next i

 

 

 

 

 

64

Поворот относительно горизонтальной оси:

Массив

Массив

Фрагмент программного кода

до поворота

после поворота

 

n = a.GetLength(0) m = a.GetLength(1)

For i As Int32= 0 To n \ 2 - 1 For j As Int32= 0 To m -1

z = a(i, j)

a(i, j) = a (n - i -1, j) a(n- i -1, j) = z

Next j Next i

Поворот относительно вертикальной оси:

Массив

Массив

Фрагмент программного кода

до поворота

после поворота

 

n = a.GetLength(0) m = a.GetLength(1)

For i As Int32= 0 To n - 1 For j As Int32= 0 To m \2 - 1

z = a(i, j)

a(i, j) = a(i, m- j -1) a(i, m - j - 1) = z

Next j Next i

Поворот относительно главной диагонали:

Массив

Массив

Фрагмент программного кода

до поворота

после поворота

 

n = a.GetLength(0)

for i As Int32= 0 to N - 1 for j As Int32= 0 to i - 1

z = a ( i, j )

a ( i, j ) = a ( j, i ) a( i, j ) = z

next j next i

65

Задача 6.14. В двумерном массиве вставить после каждого столбца, начиная со второго, первый столбец.

Интерфейс задачи представлен на рис. 6.14. Программный код:

Public Class Form1

'инициализация массива

Dim a(,) As Int32 = {{7, 2, 3, 5}, {7, 1, 2, 6}, _ {7, 1, 4, 8}, {7, 1, 3, 9}}

Sub out_put(ByVal a(,) As Int32, ByVal b As DataGridView) b.ColumnHeadersVisible = False

b.RowHeadersVisible = False b.RowCount = a.GetLength(0) b.ColumnCount = a.GetLength(1)

For i As Int32 = 0 To a.GetUpperBound(0) For j As Int32 = 0 To a.GetUpperBound(1)

b.Columns(j).Width = 40 b.Rows(i).Cells(j).Value = _

Convert.ToString(a(i, j))

Next j Next i

End Sub

Private Sub Button1_Click(...) Handles Button1.Click Dim kol, n, m, k As Int32

n = a.GetLength(0) : m = a.GetLength(1) kol = 2 * m - 1 'новое количество столбцов 'расширение размера массива по столбцам 'с сохранением исходных значений элементов

ReDim Preserve a(n - 1, kol - 1) k = 2

'цикл по вставке первого столбца

While k <= kol

'сдвиг столбцов вправо на одну позицию

For j As Int32 = kol - 1 To k Step -1 For i As Int32 = 0 To n - 1

a(i, j) = a(i, j - 1)

Next i Next j

'вставка первого столбца на освободившееся место

For i As Int32 = 0 To n - 1 a(i, k) = a(i, 0)

Next i

66

k += 2

End While 'конец цикла по вставке 'вывод измененного массива out_put(a, DataGridView2)

End Sub

Private Sub Form1_Load(...) Handles MyBase.Load

'вывод исходного массива

out_put(a, DataGridView1)

End Sub

End Class

Рис. 6.14 Интерфейс задачи 6.14

Задача 6.15. В двумерном массиве удалить все строки, содержащие 0.

Интерфейс задачи представлен на рис. 6.15. Программный код:

Public Class Form1

Dim a(,) As Int32 = {{1, 2, 3, 4, 1}, {2, 1, 0, 7, 1}, _ {7, 1, 4, 3, 8}, {7, 1, 0, 3, 2}}

Sub out_put(ByVal a(,) As Int32, _ ByVal b As DataGridView)

'Запрет на вывод заголовочных столбца и строки таблицы b.ColumnHeadersVisible = False b.RowHeadersVisible = False

'Задание количества строк и столбцов в таблице b.RowCount=a.GetLength(0): b.ColumnCount=a.GetLength(1)

67