Основы работы в VBA. Массивы
6. Примеры решения задач с двумерными массивами
Пример 1. Дан массив А(n, m). Составить программу для подсчета количества положительных элементов массива в каждой строке и количество отрицательных элементов в каждом столбце.
Поскольку необходимо получить количество отрицательных элементов в столбцах, то после ввода значений элементов массива, на этапе подсчета отрицательных элементов внешний цикл открывается по индексу столбца, а во внутреннем цикле (индекс по строке) перебираются все элементы сначала первого столбца, затем второго и т.д. При этом определяется количество отрицательных элементов в каждом столбце.
Sub primer_1()
Randomize Timer
Dim a() As Integer
Dim n As Integer, m As Integer, massiv As String
Dim i As Integer, j As Integer
Dim str As String, stolb As String
Dim k_pol As Integer, k_otr As Integer
n = InputBox("Количество строк равно", "Запрос 1 из 2")
m = InputBox("Количество столбцов равно", "Запрос 2 из 2")
massiv = " ": str = " ": stolb = " "
ReDim a(n, m) As Integer
'заполнение массива случайными целыми числами
For i = 1 To n
For j = 1 To m
a(i, j) = 50 - Int(Rnd() * 100)
massiv = massiv & a(i, j) & Chr(9)
Next j
massiv = massiv & Chr(13)
Next i
'инициализация счетчиков положительных и отрицательных
'элементов
k_pol = 0: k_otr = 0
'подсчет положительных элементов в каждой строке
For i = 1 To n
k_pol = 0
For j = 1 To m
If a(i, j) >= 0 Then k_pol = k_pol + 1
Next j
str = str & k_pol & Chr(9)
Next i
'подсчет отрицательных элементов в каждом столбце
For j = 1 To m
k_otr = 0
For i = 1 To n
If a(i, j) < 0 Then k_otr = k_otr + 1:
Next i
stolb = stolb & k_otr & Chr(9)
Next j
'Команда MsgBox... записывается в редакторе VB в одну строку
MsgBox "Исходный массив:" & Chr(13) & massiv & Chr(13) & Chr(13) & "Количество положительных элементов по строкам:" & Chr(13) & str & Chr(13) & Chr(13) & "Количество отрицательных элементов по столбцам:" & Chr(13) & stolb, , "Ответ"
End Sub
Результат выполнения программы:
Пример 2. Ввести массив А(n, m). Найти номер столбца, сумма элементов которого минимальна.
Sub primer_2()
Randomize Timer
Dim a() As Integer
Dim n As Integer, m As Integer, massiv As String
Dim i As Integer, j As Integer
Dim min As Integer, jmin As String, sum As Integer
n = InputBox("Количество строк равно", "Запрос 1 из 2")
m = InputBox("Количество столбцов равно", "Запрос 2 из 2")
massiv = "": jmin = ""
ReDim a(n, m)
'заполнение массива случайными целыми числами
For i = 1 To n
For j = 1 To m
a(i, j) = 50 - Int(Rnd() * 100)
massiv = massiv & a(i, j) & Chr(9)
Next j
massiv = massiv & Chr(13)
Next i
'вычисление суммы элементов 1-го столбца
sum = 0
For i = 1 To n
sum = sum + a(i, 1)
Next i
min = sum: jmin = "1"
For j = 1 To m
sum = 0
'вычисление суммы в столбце
For i = 1 To n
sum = sum + a(i, j)
Next i
'поиск минимальной суммы
If sum < min Then
min = sum
jmin = j
ElseIf sum = min And jmin <> "1" Then
jmin = jmin & "," & j
End If
Next j
'Команда MsgBox... записывается в редакторе VB в одну строку
MsgBox "Исходный массив:" & Chr(13) & massiv & Chr(13) & Chr(13) & "Минимальная сумма в " & jmin & " столбце(ах). Она равна " & min, , "Ответ"
End Sub
Результат выполнения программы:
Пример 3. Ввести массив А(n, n). Найти максимальный и минимальный элементы главной диагонали. Заменить все элементы главной диагонали на максимальный элемент, побочной – на минимальный. Если массив содержит нечетное число строк и столбцов, то центральный элемент заменить на 0.
Sub primer_3()
Randomize Timer
Dim a() As Integer
Dim n As Integer, min As Integer, max As Integer
Dim i As Integer, j As Integer
n = Cells(1, 4)
ReDim a(n, n)
'очистка рабочего листа от посторонних надписей
For i = 1 To 10 * n
For j = 1 To 10 * n
Cells(i + 1, j) = ""
Next j
Next i
'заполнение массива случайными целыми числами
'вывод массива в рабочий лист Excel
Cells(3, 1) = "Исходный массив:"
For i = 1 To n
For j = 1 To n
a(i, j) = 50 - Int(Rnd() * 100)
Cells(i + 3, j) = a(i, j)
Next j
Next i
'поиск максимального и минимального элемента
'главной диагонали
min = a(1, 1): max = a(1, 1)
For i = 1 To n
If a(i, i) < min Then min = a(i, i)
If a(i, i) > max Then max = a(i, i)
Next i
'замена элементов главной диагонали на max
'замена элементов побочной диагонали на min
For i = 1 To n
a(i, i) = max
a(i, n - i + 1) = min
Next i
'замена центрального элемента на 0 при нечетном
'размере матрицы
If Int(n / 2) <> n / 2 Then a(Int(n / 2) + 1, Int(n / 2) + 1) = 0
'вывод на печать преобразованного массива
Cells(n + 5, 1) = "Пребразованный массив:"
For i = 1 To n
For j = 1 To n
Cells(n + 5 + i, j) = a(i, j)
Next j
Next i
End Sub
Результат выполнения программы:
Пример 4. Найти сумму элементов,
расположенных: над главной диагональю, под главной диагональю, над побочной
диагональю, под побочной диагональю квадратной матрицы А(n, n).
Sub primer_4()
Randomize Timer
Dim a() As Integer
Dim n As Integer, i As Integer, j As Integer
Dim sum As Integer
n = Cells(1, 4)
ReDim a(n, n)
'очистка рабочего листа от посторонних надписей
For i = 1 To 10 * n
For j = 1 To 10 * n
Cells(i + 1, j) = ""
Next j
Next i
'заполнение массива случайными целыми числами
'вывод массива в рабочий лист Excel
Cells(3, 1) = "Исходный массив:"
For i = 1 To n
For j = 1 To n
a(i, j) = 50 - Int(Rnd() * 100)
Cells(i + 3, j) = a(i, j)
Next j
Next i
'сумма элементов над главной диагональю
sum = 0
For i = 1 To n - 1
For j = i + 1 To n
sum = sum + a(i, j)
Next j
Next i
Cells(n+5, 1)="Сумма элементов над главной диагональю равна"& sum
'сумма элементов под главной диагональю
sum = 0
For i = 2 To n
For j = 1 To i - 1
sum = sum + a(i, j)
Next j
Next i
Cells(n+6, 1)="Сумма элементов под главной диагональю равна"& sum
'сумма элементов над побочной диагональю
sum = 0
For i = 1 To n - 1
For j = 1 To n - i
sum = sum + a(i, j)
Next j
Next i
Cells(n+7, 1)="Сумма элементов над побочной диагональю равна"& sum
'сумма элементов под побочной диагональю
sum = 0
For i = 2 To n
For j = n - i + 2 To n
sum = sum + a(i, j)
Next j
Next i
Cells(n+8, 1)="Сумма элементов под побочной диагональю равна"& sum
End Sub
Результат выполнения программы:
Пример 5. Дана матрица А(n,
m). Отсортировать каждую строку в порядке возрастания.
Для решения задачи:
1) вводим размеры массива А(n, m) и значения его элементов;
2) просматриваем строки массива и упорядочиваем их;
3) выводим матрицу.
Для решения этой задачи воспользуемся алгоритмом упорядочивания одномерного массива. Сравниваем между собой первый и второй элементы строки массива и переставляем их, если это необходимо в порядке возрастания. Затем то же самое проделываем со вторым и третьим элементами и т.д. до конца строки массива. В результате этих сравнений и перестановок наибольшее число строки окажется последним.
Второй этап сравнений и перестановок будем производить для (n – 1) элементов строки, начиная с первого. В этом случае предпоследним окажется наибольший из (n – 1) членов строки массива. Уменьшая каждый раз количество рассматриваемых элементов на единицу, операции сравнения и перестановок закончим тогда, когда останется всего один элемент строки массива.
Подобные операции выполняем для каждой строки по отдельности.
Перестановку элементов будем осуществлять с помощью промежу-точной переменной prom.
Sub primer_5()
Dim a() As Integer
Dim n As Integer, m As Integer, i As Integer
Dim j As Integer, prom As Integer, k As Integer
n = Cells(1, 4)
m = Cells(2, 4)
ReDim a(n, m)
'очистка рабочего листа от посторонних надписей
For i = 1 To 10 * n
For j = 1 To 10 * n
Cells(i + 2, j) = ""
Next j
Next i
'заполнение массива случайными целыми числами
'вывод массива в рабочий лист Excel
Cells(4, 1) = "Исходный массив:"
For i = 1 To n
For j = 1 To m
a(i, j) = 50 - Int(Rnd() * 100)
Cells(i + 4, j) = a(i, j)
Next j
Next i
'сортировка двумерного массива по строкам
For i = 1 To n
'сортировка строки массива
For k = m - 1 To 1 Step -1
For j = 1 To k
If a(i, j) > a(i, j + 1) Then
'перестановка соседних элементов массива
prom = a(i, j)
a(i, j) = a(i, j + 1)
a(i, j + 1) = prom
End If
Next j
Next k
Next i
'вывод на печать массива с отсортированными строками
Cells(n + 6, 1) = "Преобразованный массив:"
For i = 1 To n
For j = 1 To m
Cells(i + n + 6, j) = a(i, j)
Next j
Next i
End Sub
Результат выполнения программы:
Пример 6. Дана матрица А(n,
m). Отсортировать каждый столбец в порядке
убывания.
Sub primer_6()
Dim a() As Integer
Dim n As Integer, m As Integer, i As Integer
Dim j As Integer, prom As Integer, k As Integer
n = Cells(1, 4)
m = Cells(2, 4)
ReDim a(n, m)
'очистка рабочего листа от посторонних надписей
For i = 1 To 10 * n
For j = 1 To 10 * m
Cells(i + 2, j) = " "
Next j
Next i
'заполнение массива случайными целыми числами
'вывод массива в рабочий лист Excel
Cells(4, 1) = "Исходный массив:"
For i = 1 To n
For j = 1 To m
a(i, j) = 50 - Int(Rnd() * 100)
Cells(i + 4, j) = a(i, j)
Next j
Next i
' сортировка двумерного массива по столбцам
For j = 1 To m
'сортировка столбцов массива
For k = n - 1 To 1 Step -1
For i = 1 To k
If a(i, j) < a(i + 1, j) Then
'перестановка соседних элементов массива
prom = a(i, j)
a(i, j) = a(i + 1, j)
a(i + 1, j) = prom
End If
Next i
Next k
Next j
'вывод на печать массива с отсортированными строками
Cells(n + 6, 1) = "Преобразованный массив:"
For i = 1 To n
For j = 1 To m
Cells(i + n + 6, j) = a(i, j)
Next j
Next i
End Sub
Результат выполнения программы:
Пример 7. Сложить матрицы A(n, m) и B(n, m) с получением матрицы C(n, m).
Результатом суммы матриц является новая матрица той же размерности, каждый элемент которой равен сумме соответствующих элементов исходных матриц. Сложение соответствующих элементов достигается использованием одних и тех же значений счетчиков цикла, т.е. A(1, 2) складывается с B(1, 2) и результат присваивается элементу C(1, 2).
Sub primer_7()
Dim a() As Integer, b() As Single, c() As Single
Dim n As Integer, m As Integer, i As Integer
Dim j As Integer
n = Cells(1, 4)
m = Cells(2, 4)
ReDim a(n, m): ReDim b(n, m): ReDim c(n, m)
'очистка рабочего листа от посторонних надписей
For i = 1 To 10 * n
For j = 1 To 10 * m
Cells(i + 2, j) = ""
Next j
Next i
'заполнение матриц А и В случайными числами
'вывод матриц в рабочий лист Excel
Cells(4, 1) = "Матрица А:"
Cells(4, m + 2) = "Матрица B:"
For i = 1 To n
For j = 1 To m
'матрица А
a(i, j) = 50 - Int(Rnd() * 100)
Cells(i + 4, j) = a(i, j)
'матрица В
b(i, j) = 50 - Int(Rnd() * 1000) / 10
Cells(i + 4, j + m + 2) = b(i, j)
Next j
Next i
Cells(n + 4 + 2, 1) = "Матрица C:"
'сложение матриц
For i = 1 To n
For j = 1 To m
c(i, j) = a(i, j) + b(i, j)
Cells(i + n + 4 + 3, j) = c(i, j)
Next j
Next i
End Sub
Результат выполнения программы:
Пример 8. Умножить матрицу А(n, m) на матрицу B(m, h).
Сложность заключается в том, что результатом будет матрица и для формирования ее столбцов нужен еще один цикл.
По правилам математики, можно умножать матрицы только в том случае, если количество столбцов первой равно количеству строк во второй. При этом в результирующей матрице будет строк столько же, сколько было в первой матрице, а столбцов столько же, сколько их было во второй. Это можно показать формулой A(n, m) × B(m, h) = C(n, h).
В ходе умножения матриц использовано три цикла. Первый, со счетчиком i, задает порядок умножения строк матрицы А. Второй, со счетчиком i2, задает перебор столбцов матрицы В. В третьем цикле, со счетчиком j, происходит подсчет суммы произведений элементов i-й строки матрицы А и i2-го столбца матрицы В. Сумма присваивается очередному элементу матрицы C, и переменная sum обнуляется.
Sub primer_8()
Dim a() As Integer, b() As Single, c() As Single
Dim n As Integer, m As Integer, h As Integer
Dim i As Integer, j As Integer, i2 As Integer
Dim sum As Single
n = Cells(1, 4)
m = Cells(2, 4)
h = Cells(3, 4)
ReDim a(n, m): ReDim b(m, h): ReDim c(n, h)
'очистка рабочего листа от посторонних надписей
For i = 1 To 10 * n
For j = 1 To 10 * m
Cells(i + 3, j) = " "
Next j
Next i
'заполнение матриц А случайными целыми числами
'вывод матрицs в рабочий лист Excel
Cells(5, 1) = "Матрица А:"
For i = 1 To n
For j = 1 To m
a(i, j) = 50 - Int(Rnd() * 100)
Cells(i + 5, j) = a(i, j)
Next j
Next i
'заполнение матриц B случайными числами
'вывод матрицs в рабочий лист Excel
Cells(5, m + 2) = "Матрица B:"
For i = 1 To m
For j = 1 To h
b(i, j) = 50 - Int(Rnd() * 1000) / 10
Cells(i + 5, j + m + 2) = b(i, j)
Next j
Next i
'умножение матриц А и В
For i = 1 To n 'номера строк матрицы A
For i2 = 1 To h 'номера столбцов матрицы B
sum = 0
For j = 1 To m 'элементы строки A
sum = sum + a(i, j) * b(j, i2)
Next j
c(i, i2) = sum 'формируем матрицу C
Next i2
Next i
Cells(n + 5 + 2, 1) = "Матрица C:"
For i = 1 To n
For j = 1 To h
Cells(i + n + 5 + 2, j) = c(i, j)
Next j
Next i
End Sub
Результат выполнения программы:
Пример 9. Умножить матрицу A(n, m) на вектор V(m).
Согласно правилам математики, матрицу можно умножить на вектор только в том случае, если вектор имеет количество элементов, равное количеству столбцов матрицы. Результатом умножения матрицы на вектор является новый вектор, который содержит столько элементов, сколько было строк в матрице.
Умножение массивов происходит во внутреннем цикле. В нем подсчитывается сумма произведений каждого элемента i-й строки матрицы со всеми элементами вектора. Затем сумма присваивается i-му элементу результирующего вектора С. Перед расчетом очередной строки переменная sum должна быть обнулена во избежание накопления суммы нескольких строк.
Sub primer_9()
Dim a() As Single, b() As Integer, c() As Single
Dim n As Integer, m As Integer, i As Integer
Dim j As Integer, sum As Single
n = Cells(1, 8)
m = Cells(2, 8)
ReDim a(n, m): ReDim b(m): ReDim c(m)
'очистка рабочего листа от посторонних надписей
For i = 1 To 10 * n
For j = 1 To 10 * m
Cells(i + 2, j) = ""
Next j
Next i
'заполнение матрицы А случайными числами
'вывод матрицы в рабочий лист Excel
Cells(4, 1) = "Матрица А:"
For i = 1 To n
For j = 1 To m
a(i, j) = 50 - Int(Rnd() * 1000) / 10
Cells(i + 4, j) = a(i, j)
Next j
Next i
Cells(4, m + 2) = "Вектор B:"
'заполнение вектора В случайными целыми числами
'вывод вектора в рабочий лист Excel
For i = 1 To m
b(i) = 50 - Int(Rnd() * 1000) / 10
Cells(5, i + m + 2) = b(i)
Next i
Cells(n + 6, 1) = "Матрица C:"
'умножение матрицы на вектор
'вывод результата в рабочий лист Excel
For i = 1 To n
sum = 0
For j = 1 To m
sum = sum + a(i, j) * b(j)
Next j
c(i) = sum
Cells(i + n + 6, 1) = c(i)
Next i
End Sub
Результат выполнения программы: