Информатика VBA. Учебное пособие по дисциплинам Информатика иИнформационные технологии
Скачать 1.05 Mb.
|
Then Если левая и правая части логического выражения одинаковы (знак «равно»), то у элемента массива нет дробной части (число целое). Ес- ли левая и правая части логического выражения различны (знак «не равно»), то у элемента массива есть дробная часть (число не целое). Этот же анализ можно выполнить с использованием функции Fix(), 77 которая аналогична функции int(), но дает другой результат для дробных отрицательных чисел. 3. Проверка кратности элемента массива какому либо числу. Наибо- лее часто возникает необходимость проверки числа на четность или нечетность. Оператор If для такого анализа может использо- вать функцию int() If int( mas(i)/2 ) <> = mas(i)/2 Then Если левая и правая части логического выражения одинаковы (знак «равно»), то элемент кратен двум (число четное). Если левая и правая части логического выражения различны (знак «не равно»), то элемент массива является нечетным числом. Этот же анализ можно выпол- нить с использованием функции Fix(), операции целочисленного де- ления ( mas(i)\2 ? mas(i)/2), либо операции вычисления остатка от де- ления - mas(i) mod 2 ? 0 (если остаток равен нулю, то число четное). Пример 5.6. Написать фрагмент программы для определения наибольшего числа в массиве D(1 To K), содержащем K элементов. ' фрагмент программы определения максимального элемента в массиве ' D_max - вспомогательная переменная, в которой будет ' сохраняться максимальное число из массива D D_max=D(1) ' задаем начальное значение переменной D_max For i=2 To K' цикл для просмотра остальных элементов массива IF D_max < D(i) Then D_max=D(i) Next . . . В примере рассматривается задача на полную выборку массива. Для поиска максимального числа в массиве переменной D_max при- сваивается значение первого элемента массива, а затем последова- тельно его значение сравнивается со всеми другими элементами. Ес- 78 ли текущее значение переменной D_max меньше, чем очередной эле- мент массива, то значение этого элемента записывается в D_max. Ес- ли D_max больше или равно D(i), то значение D_max не изменяется. Таким образом, в переменной D_max всегда сохраняется наибольшее число из просмотренных элементов, а после завершения цикла - из всех элементов массива. Иногда переменную D_max называют бу- ферной переменной. Пример 5.7. Написать фрагмент программы для определения индекса наибольшего отрицательного числа в массиве D, содержаще- го K элементов. В данном примере рассматривается задача на частичную выбор- ку элементов массива. Такая задача имеет два важных отличия от предыдущей задачи. Первое отличие заключается в том, что в качест- ве начального значения буферной переменной, в которой будет со- храняться максимальный элемент, нельзя брать первое число из мас- сива, т.к. этот элемент может быть положительным или равным нулю. Второе отличие - при сравнении очередного элемента с буферной пе- ременной следует контролировать знак этого элемента. Кроме этого, при выводе результата следует предусмотреть в программе ситуацию, когда в массиве не окажется отрицательных чисел. Для определения начального значения вспомогательной пере- менной можно организовать цикл с поиском первого отрицательного элемента массива. Если он завершится досрочно через команду Exit For , то параметр цикла i будет равен индексу первого отрицательного элемента. Если же цикл завершится нормально (через оператор Next), то это будет означает, что в массиве нет отрицательных элементов и надо выдать сообщение об этом. Фрагмент программы для такого подхода может быть следующим. 79 ' поиск первого максимального отрицательного элемента и его индекса For i=1 To k If D(i) < 0 Then Exit For Next If i > k Then ' если параметр цикла i равен значению k+1, то цикл ' завершился нормально, т.е. в массиве нет отрицательных чисел MsgBox " В массиве нет отрицательных чисел" Else Buf=D(i)' первое отрицательное число заносим в Buf Ind=i' и запоминаем его индекс - i For j=i+1 To k If D(j) <0 AND Buf < D(j) Then Buf=D(j) ' сохраняем значение очередного ' элемента в буферной переменной Ind=j' сохраняем значение индекса ' очередного претендента на максимум End If Next j ' Конец цикла For j=i+1 To k ' печать результата MsgBox " Максимальный отрицательный элемент D(" _ &Ind& ")=" & Buf End If ' конец оператора If i > k Then . . . Однако более эффективным можно считать способ, когда в на- чале цикла буферной переменной задается достаточно большое число при определении минимального значения или очень маленькое число при поиске максимального элемента. Для практических задач можно задавать соответственно 10 10 или –10 10 (константы 1.Е10 или –1.Е10). Если в процессе выполнения программы заданное значение буферной переменной не изменится, то в массиве нет отрицательных чисел, ес- ли изменится – в переменной Buf будет находится максимальное от- рицательное число массива, а в переменной Ind его индекс. Фрагмент программы для этого способа может быть следующим. 80 Buf = –1.e10' начальное значение буферной переменной For i=1 To n' цикл поиска максимального отрицательного элемента If D(i) < 0 AND Buf < D(i) Then Buf = D(i) Ind = i End If Next ' Конец цикла For ' анализ результата и его вывод If Buf = -1.E10 THEN ' Если значение буферной переменной не изменилось - в массиве ' нет отрицательных чисел MsgBox " В массиве нет отрицательных чисел" ELSE ' значение буферной переменной изменилось MsgBox " Максимальный отрицательный элемент D(" _ &Ind& ")=" & Buf End If ' конец оператора If Buf = -1.E10 Then . . . ' продолжение программы 5.3 Программирование обработки двумерных массивов Двумерные массивы обозначаются переменными с двумя индек- сами и используются для представления матриц. Например, массив А(3,5) можно представить в виде таблицы: А(1,1) А(1,2) А(1,3) А(1,4) А(1,5) А(2,1) А(2,2) А(2,3) А(2,4) А(2,5) А(3,1) А(3,2) А(3,3) А(3,4) А(3,5) Первый индекс в обозначении элемента массива является номером строки, а второй - номером столбца матрицы. Так же как и одномерные массивы, размеры двумерных масси- вов должны быть определены в начале программы. Причем для ста- тически размещаемых массивов следует указать предельные значения номеров строк и столбцов массива. Например, оператор 81 Dim MAMI(4,6), A2(4,-3 To 3), B_matr(3 To 7, 6) определяет три двумерных массива, содержащих по 35 элементов в каждом и имеющих 5 строк и 7 столбцов. Для массива MAMI номера строк должны изменяться в диапазоне от 0 до 4, столбцов - в диапа- зоне от 0 до 6. Для массива A2 номера строк изменяются в том же диапазоне, а номера столбцов должны изменяться в диапазоне от -3 до 3. В матрице B_matr номера строк должны быть от 3 до 7, а столбцов от 0 до 6. Расположение многомерных массивов в памяти ЭВМ в стандар- те языка VBA не оговариваются. В отличие от одномерных массивов, где конкретный элемент массива определяется одним индексом, при обработке двумерных массивов следует сформировать все возможные сочетания численных значений двух индексов. Это реализуется с помощью двух циклов- один по индексам строк, другой по индексам столбцов. В зависимо- сти от того, какой из этих циклов будет внешним, различают две схе- мы обработки двумерных массивов - по строкам, когда внешним яв- ляется цикл по номерам строк, и по столбцам, когда внешним являет- ся цикл по номерам столбцов. ' схема обработки массива ' по строкам For i=1 To N' внешний цикл For j=1 To M' внутренний цикл ' обработка элемента А(i,j) Next ' конец внутреннего цикла j Next ' конец внешнего цикла i ' схема обработки массива ' по столбцам For j=1 To M For i=1 To N ' обработка элемента А(i,j) Next ' внутр. цикл i Next ' внешний цикл j При написании операторов Next для наглядности можно допи- сать имена индексов соответствующего цикла. Однако, если их пере- путать, то при выполнении программы будет выдано сообщение об ошибке. 82 Схема обработки по строкам заключается в следующем. Сначала индексы i и j получают значение единицы и происходит обработка элемента А(1,1). После этого индекс j увеличивается на единицу, а индекс i остается прежним. В результате происходит последователь- ная обработка элементов 1-ой строки: А(1,2), А(1,3), А(1,4), ... , А(1,M). После завершения внутреннего цикла увеличивается значе- ние переменной i, и при выполнении цикла по индексу j осуществля- ется обработка 2-ой строки матрицы и т.д. Аналогичный процесс происходит при обработке по столбцам, только здесь изменяется ин- декс i при фиксированном номере столбца j. Ввод-вывод двумерных массивов может быть организован таки- ми же способами, что и ввод-вывод одномерных массивов. Однако при вводе-выводе двумерных массивов переменной длины, когда при составлении программы неизвестно количество строк и столбцов, их количество должно быть определено перед началом работы с масси- вом. Пример 5.8. Написать фрагмент программы для определения сумм элементов каждого столбца матрицы М(5,7) и записи получен- ных значений в одномерный массив. Исходная матрица расположена на активном листе таблицы Excel. Полученный массив с суммами столбцов поместить в восьмую строку этой же таблицы. В этой программе следует использовать схему обработки дву- мерного массива по столбцам. Сумма элементов каждого столбца формируется в переменной S и записывается в одномерный массив Summa, содержащий 7 элементов. Option Explicit ' запрет на использование необъявленных переменных Sub Пример_5_8() Dim Mas(4, 6) As Single Dim Summa(6) As Single, S As Single Dim i As Integer, j As Integer ' ввод массива из таблицы Excel по строкам 83 For i = 1 To 5 For j = 1 To 7 Mas(i - 1, j - 1) = Cells(i, j) Next Next For j = 0 To 6 ' внешний цикл по столбцам S = 0 ' подготовка переменной для накапливания суммы For i = 0 To 4 ' внутренний цикл по строкам S = S + Mas(i, j) ' вычисление суммы j-го столбца Next ' конец внутреннего цикла по параметру i Summa(j) = S ' запись суммы столбца в одномерный массив Next ' конец внешнего цикла по параметру j Cells(7 , 1) = "Сумма элементов по столбцам" For i = 1 To 7 Cells(8,i)=Summa(i-1) ' запись массива Summa в 8-ю строку таблицы Next End Sub Тестовые данные и результат отладки программы показаны на рисунке 5.3. Рисунок 5.3 - Данные и результат отладки программы «Пример_5_8» Пример 5.9. Написать фрагмент программы транспонирования массива T размером N×N. 84 For i=1 To N–1 For j=i+1 To N ' перестановка элементов T(i,j) и T(j,i) R = T(i, j) T(i, j)=T(j, i) T(j, i)=R Next Next Этот фрагмент программы переставляет местами строки и столбцы матрицы с одинаковыми номерами. При такой перестановке элементы T(i,j) и T(j,i) должны поменяться местами, например, Т(1,3) должен занять место Т(3,1) и наоборот. Перестановка элемен- тов строки и столбца массива с одинаковыми номерами осуществля- ется во внутреннем цикле, а во внешнем цикле обеспечивается пере- ход к следующей строке. Так как начальное значение параметра внутреннего цикла j равно i+1, перестановка элементов новой строки начинается не с первого элемента строки, а с элемента T(i,i+1) и продолжается от этого элемента вправо по строке. Элементы строки, расположенные левее главной диагонали, уже переставлены. Для перестановки двух элементов местами целесообразно вве- сти дополнительную переменную соответствующего типа, а саму пе- рестановку осуществлять по следующей схеме: 1- й шаг - значение первого элемента присваивается рабочей пере- менной (например «R»); 2- ой шаг - значение второго элемента записывается в первый эле- мент (при этом старое значение первого элемента пропа- дает, поэтому оно предварительно было сохранено в ра- бочей переменной); 3- ий шаг - старое значение первого элемента из рабочей перемен- ной R записывается во второй элемент. 85 Пример 5.10. Написать фрагмент программы формирования единичной матрицы размером 5×5. Отличительной особенностью такого класса задач является то, что требуется записать в массив данные, подчиняющиеся какому-то закону. В этом случае следует запрограммировать закон создания та- кого массива, а не задавать эти значения оператором ввода. ' Фрагмент программы формирования единичной матрицы ' E(i,j )=1, если i=j и E(i,j)=0, если i не равно j For i=1 To 5 For j=1 To 5 E( i, j )=0.' записываем в строку i нули Next E(i,i)=1. ' записываем в элемент главной диагонали единицу Next Пример 5.11. Написать программу перестановки минимального положительного и максимального отрицательного элементов матри- цы размером 6×5. Исходные данные прочитать из текстового файла, а полученную матрицу вывести в другой текстовый файл. Option Explicit ' запрет на использование в программе ' необъявленных переменных Sub Пример_5_11() Dim Mas(5, 4) As Single Dim Min_E As Single ' минимальное положительное число в массиве Dim i_Min As Integer, j_Min As Integer ' его индексы Dim Max_E As Single ' максимальное отрицательное число в массиве Dim i_Max As Integer, j_Max As Integer ' его индексы Dim i As Integer, j As Integer ' рабочие переменные ' ввод массива из файла Open "dat2.txt" For Input As #1 ' открываем файл для ввода Open "res2.txt" For Output As #2 ' открываем файл для вывода Print #2, " Исходная матрица Mas(6,5)" For i = 0 To 5 For j = 0 To 4 86 If EOF(1) = True Then ' вывод сообщения об ошибке в диалоговое окно Excel и файл вывода MsgBox "В файле ""dat2.txt"" мало данных: i=" & i & ", j=" & j Print #2, Chr(13), " В файле ""dat2.txt"" мало данных: i="; i; ", j="; j GoTo 99 End If Input #1, Mas(i, j) ' считываем из файла очередной элемент Print #2, Mas(i, j), ' выводим очередной элемент в файл, ' но не закрываем строку Next j Print #2, Chr(13) ' заканчиваем вывод строки матрицы Next i ' поиск индексов мин. полож. и макс. отрицательного элементов Min_E = 10000000000# ' задаем начальное значение +1.е10 Max_E = -10000000000# ' задаем начальное значение -1.е10 For i = 0 To 5 ' внешний цикл по строкам For j = 0 To 4 ' внутренний цикл по столбцам If Mas(i, j) > 0 And Mas(i, j) < Min_E Then Min_E = Mas(i, j) i_Min = i: j_Min = j ' запоминаем индекс миним. полож. числа End If If Mas(i, j) < 0 And Mas(i, j) > Max_E Then Max_E = Mas(i, j) i_Max = i: j_Max = j ' запоминаем индекс макс. отриц. числа End If Next j ' конец внутреннего цикла по параметру j Next i ' конец внешнего цикла по параметру i ' проверка If Min_E = 10000000000# Or Max_E = -10000000000# Then ' нужных чисел нет If Min_E = 10000000000# Then ' нет положительных чисел MsgBox "В массиве нет положительных чисел" #2, "В массиве нет положительных чисел" End If ' конец If Min_E = +1e10 If Max_E = -10000000000# Then ' нет отрицательных чисел MsgBox "В массиве нет отрицательных чисел" #2, "В массиве нет отрицательных чисел" End If ' конец If Max_E = -1e10 Else 87 ' в массиве есть положительные и отрицательные числа #2, "Минимальное положительное число Mas("; i_Min + 1; _ ","; j_Min + 1; ")="; Min_E #2, "Максимальное отрицательное число Mas("; i_Max + 1; _ ","; j_Max + 1; ")="; Max_E Mas(i_Min, j_Min) = Max_E ' меняем элементы местами Mas(i_Max, j_Max) = Min_E ' выводим полученную матрицу 0> |