Практическая работа по теме 3. Модульное программирование

advertisement
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Практическая работа по теме 3. Модульное
программирование
Создание и инициализация массивов. Изменение размеров массива.
Поиск в массиве. Тип коллекции – набор объектов (set).
Использование динамического класса ArrayList. Использование хэш
таблицы – коллекции Hashtable. Использование коллекции SortedList.
Использование очереди. Использование стека. Методы: процедуры и
функции. Обработка даты и времени.
Практическая работа по теме 3. Модульное программирование .............................................1
Задание 1. Создание и инициализация массивов ...................................................................1
Задание 2. Изменение размеров массива.................................................................................6
Задание 3. Поиск в массиве ......................................................................................................8
Задание 4. Тип коллекции – набор объектов (set) ................................................................11
Задание 5. Использование динамического класса ArrayList ...............................................13
Задание 6. Использование хэш-таблицы – коллекции Hashtable ........................................17
Задание 7. Использование коллекции SortedList ..................................................................20
Задание 8. Использование очереди (набора, работающего по принципу FIFO) ...............23
Задание 9. Использование стека (набора, работающего по принципу LIFO)....................24
Задание 10. Методы: процедуры и функции.........................................................................26
Задание 11. Обработка даты и времени .................................................................................32
Задание 1. Создание и инициализация массивов
Задача
Создать обычный типизированный массив (класс System.Array),
выполнить его инициализацию (заполнение начальными значениями)
как при объявлении массива, так и в ходе выполнения программы,
просмотреть массив поэлементно.
Решение
Рассмотреть все возможные способы описания и инициализации
обычных типизированных массивов, создаваемых в .NET как
экземпляры класса System.Array. Использовать операторы цикла для
организации работы с элементами массивов.
Обсуждение
До этого момента мы рассматривали простые типы данных. Теперь
выясним, как можно хранить связанную, структурную информацию.
В платформе .NET для структурированных данных применяется
понятие «коллекция». Термин «коллекция» (collection) относится к
особому типу объектов, которые способны хранить внутри себя другие
объекты и позволяет работать с ними или по отдельности, или как с
группой.
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Простейший тип коллекции – набор объектов, сгруппированный без
какого-либо определенного порядка, его часто называют набором
(set). Коллекция, в которой объекты хранятся в определенной
последовательности, называется списком (list).
Среди различных типов коллекций, кроме списков и наборов, также
различают: хэш-таблицы, стэки, очереди, сортированные списки.
У них различная функциональность и каждый тип предназначен для
решения определенных задач. В .NET коллекции описаны в
пространстве имен System.Collection.
Начнем рассмотрение принципов работы с коллекциями с одной из
форм коллекции – массивами данных. Массивы представляют собой
простейшую форму структурированных данных, они являются
коллекцией, хотя описаны в другом пространстве имен –
System.Array.
Массивы применяются для хранения множества элементов данных,
доступ к которым осуществляется по общему имени и индексу,
добавляемому автоматически к каждой переменной массива.
Разберемся с тем, как эти индексы формируются.
В VB .NET индексация массивов начинается с нуля (это можно
изменять, но не рекомендуется). Таким образом, при описании
одномерного массива в скобках указывается верхняя граница индекса
(нижняя, по умолчанию, всегда равна нулю). При описании
многомерного массива в скобках через запятую указываются верхние
границы индекса по каждому измерению.
Рассмотрим примеры описания массивов:
Dim B(19) As Integer – одномерный массив B из 20 целых чисел;
Dim SA(6) As String – одномерный массив SA на 7 строк;
Private SB(4, 1) As Integer – создание двумерного массива SB (5x2)
целых чисел;
Public RA(1, 1, 1) As Double – трехмерный (2x2x2) массив RA
вещественных чисел.
Задание начальных значений элементов массива можно выполнять
как с помощью обычных операторов присваивания в коде программы,
так и непосредственно при описании массива.
Например, был объявлен одномерный массив на две строки:
Dim SA(1) As String
Далее, в ходе программы выполняется инициализация элементов
массива SA:
SA(0)="Пн"
SA(1)="Вт"
Не требуется помещать данные в каждый элемент массива, нет даже
необходимости сохранять элементы последовательно.
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Dim strHouse(4) As String
strHouse(1)=”Jones”
strHouse(4)=”Goldstein”
strHouse(3)=”Soprano”
В случае двумерного или любого n-мерного массивов необходимо
четко соблюдать систему индексации элементов массива:
SB(0,0)=1: SB(0,1)=2
SB(1,0)=3: SB(1,1)=4
RA(0,0,0)=0.1: RA(0,0,1)=0.1
RA(0,1,0)=0.3: RA(0,1,1)=0.4
Инициировать (задавать начальные значения) массив можно
непосредственно при его описании. В этом случае есть
дополнительные синтаксические особенности для строк и n-мерных
массивов. Рассмотрим эти особенности в примерах:
Dim SA() As String = {"Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"} – обратите
внимание на фигурные скобки и кавычки;
Private SB(,) As Integer = {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}} – обратите
внимание на пары фигурных скобок;
public RA( , , ) as Double={{{0.1,0.2},{0.3,0.4}},{{0.5,0.6},{0.7,0.8}}}
При инициализации массива непосредственно в операторе описания
начальные значения каждого элемента указываются в фигурных
скобках и разделяются запятыми.
Обратите внимание, что в случае, когда инициализация массива
производится непосредственно в операторе описания, верхние
границы индексов не указываются, так как компилятор VB .NET
определяет их по реальному количеству элементов, указанных в
правой части соответствующего оператора.
После описания массива с его элементами можно работать как с
обычными переменными соответствующего типа, в частности, они
могут быть частью выражений левой и правой части оператора
присваивания. Значения индекса указывается в скобках через
запятую.
Обычные массивы являются типизированными, так как хранят данные,
относящиеся к одному типу. Это обстоятельство позволяет не делать
дополнительных проверок при обработке отдельных элементов
массива.
Массивы особенно полезны, если нужно обрабатывать целый набор
элементов, как если бы это был один элемент. Например, изменить
нормы оплаты трем сотрудникам можно следующим образом:
Dim EmployeePay(2) as Integer
Dim ExtraPay As Integer=1000
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
EmployeePay(0)= EmployeePay(0)+ ExtraPay
EmployeePay(1)= EmployeePay(1)+ ExtraPay
EmployeePay(2)= EmployeePay(2)+ ExtraPay
Но, используя структуру массива, можно сделать то же самое гораздо
короче:
Sub Main()
Dim EmployeePay() As Integer = {20000,
15000, 25000}
Dim ExtraPay As Integer = 1000
Dim i As Integer
For i = 0 To 2
Console.Write(EmployeePay(i).ToString &
ControlChars.Tab)
EmployeePay(i) = EmployeePay(i) + ExtraPay
Console.WriteLine(EmployeePay(i).ToString)
Next
Console.ReadLine()
End Sub
Управляющая структура For..Next позволяет сделать запись
обработки элементов массива значительно короче. Кроме For..Next
для перебора элементов массива могут быть использованы любые
другие конструкции циклов, например, For Each..Next.
Sub Main()
Dim EmployeePay() As Integer = {20000, 15000, 25000}
Dim ExtraPay As Integer = 1000
Dim i As Integer
For Each i In EmployeePay
Console.Write(i.ToString & ControlChars.Tab)
i = i + ExtraPay
Console.WriteLine(i.ToString)
Next
Console.ReadLine()
End Sub
Массивы реализованы в .NET в классе System.Array, то есть,
создавая массив для хранения переменных любого типа, мы создаем
объект класса System.Array. Класс имеет набор свойств и методов,
которые можно вызывать с именем объекта. Например,
AA.GetUpperBound(0) возвращает значение верхней границы
одномерного массива AA (индекс 0 показывает размерность массива)
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
или AA.Clear очищает весь массив от значений. Использование
методов и свойств класса System.Array рассмотрено в примерах ниже.
Самостоятельно
Создайте приложение, в котором используются n-мерные массивы;
организован ввод элементов в описанные структуры и вывод их на
экран.
Ниже представлены примеры использования операторов цикла для
организации перебора всех элементов массива:
Sub Main()
Dim List() As String = {"Это", "просто",
"тест"}
Dim str As String
For Each str In List
Console.WriteLine(str)
Next
Console.ReadLine()
End Sub
А эта программа отобразит в консоли
число “2”:
Sub Main()
Dim AA(,) As Integer = {{3, 2, 6}, {9, 4, 6}}
Console.WriteLine(AA(0, 1).ToString)
Console.ReadLine()
End Sub
Аналогично, следующая консоль покажет
число “7”:
Sub Main()
Dim AA(,,) As Integer = {{{3, 5}, {2, 7}}, {{0,
1}, {9, 8}}}
Console.WriteLine(AA(0, 1, 1).ToString)
Console.ReadLine()
End Sub
Перебор элементов одномерного массива
удобно выполнять в счетном цикле:
Sub Main()
Dim AA() As Integer = {1, 2, 3}
Dim k As Integer
For k = 0 To AA.GetUpperBound(0)
Console.WriteLine(AA(k).ToString)
Next
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Console.ReadLine()
End Sub
В случае двумерного массива (2x3) вывод
можно организовать следующим образом:
Dim AA(,) As Integer = {{1, 2, 3}, {1, 2, 3}}
Dim j, k As Integer
For j = 0 To AA.GetUpperBound(1)-1
For k = 0 To AA.GetLength(1) - 1
Console.Write(AA(j, k).ToString &
ControlChars.Tab)
Next
Console.WriteLine()
Next
Console.ReadLine()
End Sub
Фактически, VB .NET не ограничивает массивы одной или двумя
размерностями; можно объявить массив с максимум 60
размерностями, если потребуется. Однако использовать массив более
чем с тремя размерностями не имеет смысла, лучше поискать другое
решение (например, базы данных).
Задание 2. Изменение размеров массива
Задача
Изменять значение размера массива
сохранением данных или без сохранения.
в
ходе
программы
с
Решение
Использовать команду Visual Basic .NET. ReDim с ключевым словом
Preserve при необходимости сохранения данных в массиве или ReDim
без ключа Preserve при новой инициализации массива.
Обсуждение
Массивы, которые могут изменять свои границы во время работы
программы, называют динамическими. В VB .NET существует
возможность
переопределения
верхней
границы
у
ранее
определенного массива (для многомерного массива можно
переопределять только границу по самому последнему измерению).
Для этого существует оператор ReDim.
Например, если массивы первоначально описаны как
Dim B(19) As Integer
Dim SA(6) As String
Private SB(4, 1) As Integer
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Public RA(1, 1, 1) As Double,
то в дальнейшем можно переопределить границы этих массивов
следующим образом:
Redim B(20)
ReDim SA(1)
После переопределения массив B будет состоять из 21 элемента типа
Integer, массив SA будет состоять из двух элементов типа String
(индекс первого элемента равен нулю, второго – единице).
При переопределении массива можно использовать ключевое слово
Preserve – в этом случае будут сохранены значения элементов,
существовавших до переопределения. Таким образом, достаточно
будет задать только значения новых элементов, если размер массива
увеличился.
ReDim Preserve SB(4,3)
ReDim Preserve RA(1,1,2)
После переопределения двумерный массив SB будет состоять из
двадцати элементов (пять умножить на четыре) типа Integer,
трехмерный массив RA будет состоять из двенадцати элементов
(2*2*3) типа Double.
Если размерность одномерного массива заранее неизвестна, можно
при первоначальном определении не указывать ее вообще, а указать
в дальнейшем в операторе ReDim.
Например, это можно сделать так:
Dim SA() As String, N As Integer
N=1
ReDim SA(N)
SA(0)=”Пн”
SA(1)=”Вт”
Еще одной особенностью коллекций и массивов является то, что их
можно использовать как источник данных для элементов управления
форм. Например, если в Windows форме поместить элемент
управления ComboBox (или Listbox), то можно отобразить массив
значений в этом элементе управления:
Private Sub Form12_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Dim AA() As Integer = {1, 2, 3, 4, 5, 6, 7, 8, 9}
ComboBox1.DataSource = AA
Label1.Text = ComboBox1.SelectedItem
End Sub
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Private Sub
ComboBox1_SelectedIndexChanged(ByVal
sender As System.Object, ByVal e As
System.EventArgs) Handles
ComboBox1.SelectedIndexChanged
Label1.Text = ComboBox1.SelectedItem
End Sub
Самостоятельно
1. Определите пустой числовой
одномерный
массив.
Выполните
отображение
массива
на
элемент
управления ListBox (можно
ComboBox)
в
Windows
приложении.
2. Организуйте
ввод
информации в массив в диалоговом режиме.
3. В коде программы изменяйте размер массива с сохранением
всех внесенных данных.
Объявленный
массив
будет
обрабатываться
несколькими
процедурами (обработчиками событий), следовательно, массив
должен быть описан с областью видимости уровня формы:
Dim AA() As Integer
Private Sub Form12_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Ваш код загрузки формы
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Ваш код щелчка по командной кнопке
End Sub
Задание 3. Поиск в массиве
Задача
Найти элемент массива с нужным содержанием.
Решение
Использовать методы и свойства класса System.Array.
Обсуждение
Допустим, требуется выяснить, в каком из элементов массива
содержится некоторое значение. Класс System.Array предоставляет
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
совместно используемый метод (shared-метод) IndexOf, который
возвращает позицию первого найденного включения в заданном
массиве. Например, чтобы узнать, в каком из элементов массива
содержится строка «Самолет», можно использовать выражение:
Array.IndexOf(A, “Самолет”), где A – имя массива.
Метод IndexOf возвращает целое число – индекс найденного
элемента в массиве или -1 в случае его отсутствия. Можно расширить
это выражение, добавив целочисленный параметр, задающий индекс,
от которого начинается поиск, например:
Array.IndexOf(MyArray, “Самолет”,3) – поиск начинается с индекса 3.
Можно «пройтись» по всем элементам массива и найти весь перечень
включений.
Sub Main()
Dim A() As String = {"Самолет", "вертолет", "Самолет", "пилот"}
Dim i, Index As Integer
For i = 0 To 3
Index = Array.IndexOf(A, "Самолет", i)
Console.WriteLine("Строка 'Самолет' встречается в :" & Index.ToString)
Next
Console.ReadLine()
End Sub
Самостоятельно
1. Создайте строковый массив. Отобразите его содержание в
элементе управления ListBox (можно и в ComboBox).
2. При наступлении любого события, например, по щелчку
командной кнопки, скопируйте из исходного элемента
управления (ListBox) в другой элемент управления (можно тоже
ListBox) все слова, начинающиеся на букву «т».
3. Удалите эти слова как в первом ListBox, так и в массиве.
Пример решения части задачи (поиск слов, перенос слов в другой
список, удаление слов из первого списка) приведен ниже.
При циклическом просмотре массива вы не можете удалять элементы.
Решение, приведенное ниже заключается в том, что происходит поиск
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
элемента и добавление его в другой массив, затем все найденные
элементы удаляются из первоначального ListBox методом Remove.
Опишем исходный массив:
Dim Words() As String = {"Это", "текст",
"пробы", "поиска", "буквы", "т"}
Создадим пустой динамический массив для
переноса в него найденных слов:
Dim NewWords() As String
Напишем обработчик события загрузки
формы:
Private Sub Form10_Load(ByVal sender As
Object, ByVal e As System.EventArgs)
Handles MyBase.Load
ListBox1.Items.AddRange(Words)
End Sub
В качестве обработчика щелчка по кнопке
«Найти и копировать» напишем процедуру
поиска слов и записи их в Listbox2:
Private Sub Button1_Click(ByVal sender
As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim str As String
Dim i As Integer
For Each str In Words
If str.Substring(0, 1).ToUpper = "Т" Then
ReDim Preserve NewWords(i)
NewWords(i) = str
i += 1
End If
Next
ListBox2.Items.AddRange(NewWords)
End Sub
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
По щелчку на кнопке «Удалить» необходимо
удалить найденные слова в ListBox1:
Private Sub Button2_Click(ByVal sender As
System.Object, ByVal e As System.EventArgs)
Handles Button2.Click
Dim str As String
For Each str In NewWords
ListBox1.Items.Remove(str)
Next
End Sub
Алгоритм удаления слов из исходного массива попробуйте придумать
самостоятельно. В качестве варианта можно предложить: переносить
в новый массив не слова на букву “т”, а наоборот, слова не на букву
“т”. Тогда вы получите требуемую строку в новом массиве.
При любом алгоритме действий, становится, очевидно, что работать с
массивом удобно, отображая его на элементы управления,
позволяющие динамически вставлять и удалять элементы и
автоматически изменяющие свои размеры. В самом массиве эти
действия выполнять сложнее.
Задание 4. Тип коллекции – набор объектов (set)
Задача
Рассмотреть реализацию простейшего типа коллекций – набора
объектов в .NET.
Решение
Используйте коллекцию – класс System.Enum.
Обсуждение
Простейшим
типом
коллекций
является
набор
объектов,
сгруппированных без какого-либо определенного порядка; его часто
называют набором (set). Набор, который состоит из {объект1, объект2,
объект3}, эквивалентен по своим функциям набору, состоящему из
{объект1, объект2, объект3}; порядок здесь не имеет значение.
В .NET наборы или перечисления реализованы в классе System.Enum.
В каких случаях удобно использовать перечислений?
Часто переменной приходится присваивать одно из нескольких
связанных предопределенных значений (констант). В таких случаях
можно
создать перечисляемый тип данных,
позволяющий
группировать
значения.
Перечисления
связывают
набор
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
целочисленных констант с одним именем, которое можно
использоваться в коде. Например, в следующем коде создается тип
Enum переменной ВременаГода, которая используется для
определения четырех связанных между собой констант: лето, осень,
весна, зима со значениями 0, 1, 2, 3 соответственно:
Imports System.Enum
Module Module1
При описании перечисления необходимо использовать следующий
синтаксис:
Enum ВременаГода
лето
осень
весна
зима
End Enum
При использовании перечисления необходимо объявить экземпляр
перечисления:
Sub Main()
Dim x As ВременаГода= ВременаГода. весна
Console.WriteLine(x)
Console.WriteLine(x.ToString)
Console.ReadLine()
End Sub
End Module
Использование перечислений упрощают процесс создания кода
программы, повышают уровень его читаемости. В .NET предусмотрено
множество различных внутренних констант и перечислений,
разработанных для удобства программирования, например, уже
известное вам перечисление ControlChars, включающее специальные
символы, используемые для выравнивания текста, переноса строки и
так далее.
Самостоятельно
Убедитесь в том что, имея набор констант, организованных как
перечисление, использовать их в коде программы очень удобно.
Создайте приложение, в котором будут использованы стандартные
перечисления и перечисления, созданные вами, как в примере ниже.
Imports System.Enum
Enum inst
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Международный_банковский_институт
Политехнический_Университет
Технологический_Институт
End Enum
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim r As inst
Dim Stud() As String = {"Сидоров", "Волнушкин", "Сыроежкин"}
MsgBox(Stud(0) & ControlChars.Tab &
r.Международный_банковский_институт.ToString)
MsgBox(Stud(1) & ControlChars.Tab &
r.Политехнический_Университет.ToString)
MsgBox(Stud(2) & ControlChars.Tab & r.
Технологический_Институт.ToString)
End Sub
Задание 5. Использование динамического класса ArrayList
Задача
Вам нужен одномерный массив, позволяющий динамически вставлять
и удалять элементы и автоматически изменяющий свои размеры.
Решение
Используйте коллекции – класс System.Collections.ArrayList.
Обсуждение
Обычные массивы в .NET основаны на классе Array. Как в этом
убедиться? Создайте любой массив и попробуйте вызвать методы и
свойства созданного вами объекта. Вы убедитесь в том, что
функциональность присутствует. Например, ваш объект поддерживает
свойства, содержащие длину массива, его границы, есть методы
сортировки, реверса, очистки и многое другое.
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Sub Main()
Dim AA() As Integer = {3, 23, 56, 1, 34,
76, 2}
Console.WriteLine(AA.GetLength(0))
AA.Sort(AA)
Dim i As Byte
For i = 0 To AA.GetUpperBound(0)
Console.WriteLine(AA(i))
Next
AA.Reverse(AA)
For i = 0 To AA.GetUpperBound(0)
Console.WriteLine(AA(i))
Next
Console.ReadLine()
End Sub
Но класс Array нельзя назвать динамическим, так как он не позволяет
добавлять и удалять элементы так же, как это, например, реализовано
в элементах управления ListBox или ComboBox. Рассмотрим другой
класс – ArrayList, являющийся динамическим классом.
Класс ArrayList довольно прост. Для добавления элементов в него
служит метод Add, а для удаления – Remove, RemoveRange и
RemoveAt. Два последних метода удаляют элементы на основе
номеров из индексов, тогда как Remove ищет и удаляет указанный
элемент. Вместо метода GetLength, реализованного в классе
System.Array, класс ArrayList включает эквивалентное свойство Count.
Sub Main()
Dim List As New ArrayList
List.Add("blue")
List.Add("green")
List.Add("yellow")
List.Add("red")
Dim Item As String
For Each Item In List
Console.WriteLine(Item)
Next
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Console.ReadLine()
End Sub
Удаление элемента “blue” по
номеру
индекса
выполняется
методом RemoveAt:
List.RemoveAt(0)
For Each Item In List
Console.WriteLine(Item)
Next
Console.ReadLine()
End Sub
Удаление элемента “green” с
использованием
поиска
выполняется методом Remove:
List.Remove("red")
For Each Item In List
Console.WriteLine(Item)
Next
Console.ReadLine()
Console.WriteLine("Количество
строк в масиве List: " &
List.Count.ToString)
Система определения емкости класса ArrayList заключается в
следующем: при создании объекта ArrayList для него выделяется
внутренний буфер на 16 элементов. Если требуется хранить большее
число элементов, размер буфера удваивается до 32, 64 и так далее.
Если вам заранее известно, сколько элементов будет содержать
объект ArrayList, вы можете зарезервировать требуемое пространство
сразу, указав его в конструкторе класса ArrayList. Это несколько
повысит быстродействие вашей программы.
Резервирование места для 50 элементов:
Dim List As New ArrayList(50)
Класс ArrayList слабо типизирован, то есть, все свои элементы он
хранит как базовые типы Object. Поэтому при извлечении элемента
его нужно привести к соответствующему типу:
Dim str As String = CType(List(0), String)
Такое поведение может вызывать проблемы, потому что нет способа
гарантировать, что в массив не добавлен объект неверного типа.
Для быстрого добавления ряда элементов в объект ArrayList может
служить метод AddRange:
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Sub Main()
Dim List As New ArrayList
Dim Colors() As String = {"green", "blue",
"red", "yellow"}
List.AddRange(Colors)
Dim Item As String
For Each Item In List
Console.WriteLine(Item)
Next
Console.ReadLine()
End Sub
Преобразование ArrayList в обычный типизированный массив можно
выполнить методом ToArray. Это преобразование полезно выполнять,
так как использовать объект класса ArrayList удобно для быстрой
работы с массивом значений, но для контроля типов хранимых
значений, затем можно выполнить обратное преобразование в
обычный массив.
Рассмотрим код функции, которая ищет в предложении определенные
слова и добавляет их в ArrayList. По завершении этой операции
ArrayList преобразуется в массив строк. Метод ToArray возвращает
объект Array, который нужно преобразовать в строго типизированный
массив при помощи функции CType.
Private Function FindAnimalWords(ByVal sentence As String) As String()
‘Заполнение набора
Dim Words As New ArrayList
Dim Word As String
For Each Word In sentence.Split()
Select Case Word
Case "собака", "кошка", "мышка", "слон"
Words.Add(Word)
End Select
Next
‘Преобразование ArrayList в массив и приведение общего массива
‘строго типизированному массиву с помощью функции CType()
Return CType(Words.ToArray(GetType(String)), String())
End Function
Самостоятельно
1. Выполните тестирование разработанной функции.
2. Отсортируйте элементы полученного массива или объекта
класса ArrayList, используйте методы Array.Sort и ArrayList.Sort.
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
3. Докажите, что сортировка зависит от региональных стандартов и
упорядочивает элементы в алфавитном порядке (при этом буквы
нижнего регистра располагаются раньше аналогичных букв
верхнего регистра).
Классы Array и ArrayList имеют перегруженную версию метода Sort,
которая
принимает
индексы,
определяющие
сортируемое
подмножество, и собственный объект ICompare, способный выполнять
специализированную сортировку, например, List.Sort(3,5,Nothing) –
сортировка пяти элементов, начиная с индекса 3 (или 4-го элемента).
4. Примените перегруженный метод Sort для выполнения
сортировки только указанного подмножества вашего множества
данных.
Задание 6. Использование хэш-таблицы – коллекции Hashtable
Задача
Вам нужен словарный (основанный на применении ключей) набор, или
вы хотите заменить стандартный массив System.Array на более
эффективный альтернативный вариант.
Решение
Используйте класс System.Collections.Hashtable.
Обсуждение
Класс Hashtable – это словарный набор, каждый элемент которого
индексируется по уникальному значению. Набор Hashtable идеален,
когда нужно быстро извлечь отдельные элементы, потому что он
позволяет искать элементы по соответствующим значениям ключа, а
не путем перебора всех элементов. Однако в отличие от массивов
Array или класса ArrayList он не поддерживает доступ к элементам по
номерам их индексов.
При работе с хэш-таблицей вы должны решить, какие данные
использовать для индексации элементов. Эта информация должна
быть уникальной. Она может быть основана на параметрах самого
объекта, или ее можно генерировать по требованию в форме GUID
(Globally Unique Identifier – глобальный уникальный идентификатор,
целое число, включающее 128 двоичных разрядов; в .NET входит
структура GIUD, имеющая метод GUID.NewGuid) или порядкового
номера.
Например, мы можем предполагаем использовать в качестве
индексов коды стран (US, UK) и хотим получять название
соответствующих стран, чтобы выводить их на экран. Ниже
приводится пример объекта Hashtable, в котором хранятся коды и
полные названия стран. Строка используется и как ключ (код страны)
для элемента, и как значение элемента (название страны).
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
 UK United Kingdom
 US United States
 DE Germany
Рассмотрим все особенности применения хэш-таблиц:
1. Элементы ключ/значение. Каждый элемент в Hashtable
содержит больше информации, чем элемент в Array или
ArrayList, то есть он «интеллектуальнее». Объект Hashtable
меньше связан с хранением данных в списке и больше – с
поиском и извлечением информации.
2. Вставка элементов. При использовании Hashtable можно
добавлять любое необходимое число пар ключ/значение.
При использовании простых массивов необходимо заранее
указывать их размер, а потом этот размер трудно изменять.
В случае использования объекта Hashtable (как и ArrayList)
подобных ограничений не существует.
3. Удаление элементов. Удаление элементов из объектов
Hashtable происходит с той же легкость, что и их
добавление. Подобно ArrayList, Hashtable сам размещает в
памяти пары ключ/значение.
4. Быстрый поиск информации. Коллекция Hashtable
обеспечивает быстрый поиск информации, но в сравнении
с ArrayList процесс поиска выполняется медленнее.
Рассмотрим использование объекта Hashtable на конкретном
примере. Создадим объект класса Hashtable точно так же, как это
делается в случае ArrayList или любого другого класса .NET:
Sub Main()
Dim myHashTable As New Hashtable
Затем добавляем пары ключ/значение. Напомним, что ключ – это то
же самое, что индекс позиции,.a значение – хранимые данные.
Каждый элемент запоминается с помощью метода Add().
myHashTable.Add("UK", "United Kingdom")
myHashTable.Add("US", "United States")
myHashTable.Add("DE", "Germany")
Dim CountryName As String
Этот оператор вернет значение Germany. Ключи чувствительны к
регистру, поэтому, написав следующее myHashTable("de") мы получим
нулевой результат.
CountryName = myHashTable("DE")
Console.WriteLine(CountryName)
Console.ReadLine()
End Sub
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Предложенный синтаксис добавления элементов в хэш-таблицу
прекрасно работает, но чаще используется более аккуратный и
упрощенный способ записи.
Sub Main()
Dim myHashTable As New Hashtable
myHashTable("UK") = "United Kingdom"
myHashTable("US") = "United States"
myHashTable("DE") = "Germany"
Dim CountryName As String
CountryName = myHashTable("DE")
Console.WriteLine(CountryName)
Console.ReadLine()
End Sub
Рассмотрим, каким образом производится перечисление элементов
хэш-таблицы. При перечислении общего набора используется тип
содержащихся в нем элементов. Класс Hashtable не поддерживает эту
договоренность. Вместо этого вы должны просмотреть набор
объектов DictionaryEntry. Каждому элементу набора соответствует
один объект DictionaryEntry. Получить ключ элемента позволяет
свойство DictionaryEntry.Key, а извлечь элемент набора –
DictionaryEntry.Value.
Sub Main()
Dim myHashTable As New
Hashtable
myHashTable("UK") = "United
Kingdom"
myHashTable("US") = "United
States"
myHashTable("DE") = "Germany"
Dim Item As DictionaryEntry
For Each Item In myHashTable
Console.WriteLine("Key: " &
Item.Key.ToString)
Console.WriteLine("Object: " &
Item.Value.ToString)
Console.WriteLine()
Next
Console.ReadLine()
End Sub
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Самостоятельно
1. «Побродите» по созданному объекту Hashtable, просматривая
каждый из его элементов и используя содержащиеся в них ключ
и значение.
2. Как и ArrayList, класс Hashtable хранит элементы как типы Object,
поэтому, после извлечения элементов их нужно приводить к
нужному типу. Выполните это самостоятельно.
3. К числу других полезных методов и свойствам класса Hashtable
относятся:
Метод Remove удаляет элемент из набора. Этот метод принимает
ключ элемента, который нужно удалить.
Методы Contains и ContainsKey возвращают True или False в
зависимости от того, имеется ли в хэш-таблице указанный ключ, а
метод ConstainsValue – тоже, если есть указанный объект.
Свойство Keys возвращает набор всех ключей хэш-таблицы, а
свойство Values – набор всех объектов.
Используйте все эти свойства и методы самостоятельно.
Задание 7. Использование коллекции SortedList
Задача
Вам нужен набор, автоматически
добавлении или удалении.
сортируемый
при
каждом
Решение
Класс System.Collections.SortedList сортирует элементы на основе
их ключей.
Обсуждение
Класс SortedList – это основанный на применении ключей словарный
набор, который постоянно поддерживает упорядоченное состояние
своих элементов. Конечно, это замедляет добавление/удаление
элементов. И все же эти операции с набором SortedList обычно
выполняются быстрее, чем постоянная пересортировка объекта Array
или ArrayList.
Самое важное в классе SortedList то, что он упорядочивает элементы,
опираясь на значение ключей, а не сами объекты. Рассмотрим на
конкретном примере использование сортированного словарного
набора.
Например, можно использовать отсортированный список для
хранения статей в словаре (табл. 1).
Табл.1.
Статьи энциклопедии
Ключ
Значение
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Aardvark (муравьед)
Amaryllis (амариллис)
Armadillo (броненосец)
Крупное живущее в норах ночное
копытное млекопитающее.
Осенний
цветок.
Южноафриканское
луковичное
растение.
Представитель
семейства
живущих в норах неполнозубых
млекопитающих.
Создадим Windows-форму, включающую элементы управления Label,
ComboBox и Button. Напишем процедуру загрузки формы:
Dim List As New SortedList
Private Sub Form10_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Dim item As DictionaryEntry
List("Armadillo") = "Представитель семейства живущих в норах
неполнозубых млекопитающих."
List("Amaryllis") = "Осенний цветок. Южно-африканское луковичное
растение."
List("Aardvark") = "Крупное живущее в норах ночное копытное
млекопитающее"
List("Artichoke") = "Высокое сложноцветное растение."
For Each item In List
ComboBox1.Items.Add(item.Key)
Next
End Sub
Напишем обработчик события для командной кнопки:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Label1.Text = List(ComboBox1.SelectedItem)
End Sub
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Самостоятельно
1. Разберите программный код, приведенный ниже, и используйте
его для построения консольного или Windows приложения.
2. Примените другой синтаксис для добавления полученных
объектов в отсортированный список.
3. Проверьте ситуацию в случае изменения имени файла в
каталоге С:\.
Imports System.IO
Module Module1
Sub Main()
Dim Dir As New DirectoryInfo("C:\")
Dim Files() As FileInfo
Files = Dir.GetFiles
Dim List As New SortedList
Dim File As FileInfo
For Each File In Files
List.Add(File.Name, File)
Next
Dim Item As DictionaryEntry
For Each Item In List
Console.WriteLine(CType(Item.Value,
FileInfo).Name)
Next
Console.ReadLine()
End Sub
End Module
В приведенном примере необходимо объяснить некоторые строки
кода.
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Так как процедура связана с поиском и отображение файловой
структуры, для запуска этого кода необходимо импортировать
пространство имен System.IO.
С использованием классов DirectoryInfo и FileInfo мы познакомимся
подробнее в теме «Файлы и каталоги».
Задание 8. Использование очереди (набора, работающего по
принципу FIFO)
Задача
Вам нужен набор, элементы которого будут извлекаться в порядке
добавления.
Решение
Используйте класс System.Collections.Queue – набор, работающий
по принципу «первый вошел, первым вышел» (first-in, first-out, FIFO).
Обсуждение
Очереди применяются для выполнения разных последовательных
задач. Например, в очереди можно хранить список заданий, которые
должен выполнить серверный компонент. Так как очередь является
набором FIFO, ее самые старые элементы всегда обрабатываются
первыми.
С концептуальной точки зрения, объект Queue – это массив с
динамически изменяемыми размерами, хранящий объекты во многом
аналогично объекту ArrayList. При создании очередь имеет емкость,
равную 32 элементам (если в конструкторе вы не указали другое
значение), удваивая ее при необходимости.
Для получения числа элементов очереди служит свойство Count, для
добавления элемента – метод Enqueue, а для извлечения – метод
Dequeue, который при этом удаляет элемент из очереди. Кроме того,
метод Peek позволяет извлечь следующий элемент очереди без его
удаления. Однако вы не можете извлекать объекты из очереди в
произвольном порядке или по номеру индекса.
Рассмотрим создание и использование очереди на конкретном
примере. Создадим простую очередь элементов и выполним чтение
каждого из них:
Module Module1
Sub Main()
Создание очереди
Dim Q As New Queue
Заполнение очереди элементами
Q.Enqueue("Первый вошел")
Q.Enqueue("Второй вошел")
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Q.Enqueue("Третий вошел")
Q.Enqueue("Четвертый вошел")
Q.Enqueue("Пятый вошел")
Для извлечения элементов очереди создадим объект String
Dim Item As String
Свойство Count позволяет организовать конечный цикл просмотра
очереди
Do While Q.Count > 0
Извлечение из очереди
происходит с одновременным
удалением
Item = CType(Q.Dequeue, String)
Console.WriteLine("Вышел: " &
Item)
Console.WriteLine(Q.Count.ToString
& " осталось в очереди")
Loop
Очередь пуста
Console.ReadLine()
End Sub
End Module
Самостоятельно
Организуйте ввод числовых значений, включающих нули. Используйте
очередь, как структуру, выполняющую прием входящей информации.
Создайте на основе данных из очереди массив, не имеющий нулевых
значений.
Задание 9. Использование стека (набора, работающего по
принципу LIFO)
Задача
Вам нужен набор, элементы которого будут извлекаться в обратном
порядке (иначе говоря, последний добавленный элемент должен
всегда обрабатываться первым).
Решение
Используйте тип System.Collections.Stack, который представляет
собой набор, работающий по принципу «последний вошел, первым
вышел» (last-in, first-out, LIFO).
Обсуждение
Стеки применяются в случае, если требуется, чтобы последние
добавленные элементы всегда обрабатывались первыми. Как и
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
объекты ArrayList и Queue, Stack является массивом с динамически
изменяемыми размерами. При создании стек имеет емкость, равную
32 элементам (если вы не указали другое значение в конструкторе),
удваивая ее при необходимости.
Для получения числа элементов служит свойство Count, для
добавления элемента на вершину стека – метод Push, а для
извлечения – метод Pop, который при этом удаляет элемент из стека.
Кроме того, метод Peek позволяет извлечь следующий элемент стека,
не удаляя его. Однако вы не можете извлекать объекты из стека в
произвольном порядке или по номеру индекса.
В следующем примере создается простой стек и выполняется чтение
всех его элементов:
Module Module1
Sub Main()
Создадим структуру стек
Dim S As New Stack
Разместим в стеке данные
S.Push("Первый вошедший
элемент")
S.Push("Второй вошедший
элемент")
S.Push("Третий вошедший
элемент")
S.Push("Четвертый вошедший
элемент")
S.Push("Пятый вошедший
элемент")
Извлечем элементы из стека.
После извлечения элементов стек
пуст.
Dim Item As String
Do While S.Count > 0
Item = CType(S.Pop, String)
Console.WriteLine("Вышел " & Item)
Console.WriteLine(S.Count.ToString
& " элементов осталось в стеке")
Loop
Console.ReadLine()
End Sub
End Module
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Самостоятельно
Используйте структуру стека для хранения числовой информации, на
основе которой создайте типизированный массив только четных
чисел.
Задание 10. Методы: процедуры и функции
Задача
Научиться компоновать фрагменты кода программы в виде небольших
законченных подпрограмм, оформленных специальным образом.
Решение
Описать, в соответствии с определенным в VB.NET синтаксисом,
повторяющиеся фрагменты кода в виде процедур или функций и
обеспечить доступ к этим структурам.
Обсуждение
Методы – это небольшие законченные программы, состоящие из
операторов языка программирования, оформленные специальным
образом. Методы позволяют описать одинаковые повторяющиеся
участки кода. Методы имеют имя, которое служит для вызова этих
подпрограмм в коде основной программы, в кодах других подпрограмм
или в собственном коде (рекурсия).
По своей функциональности методы условно можно разделить на
процедуры (sub) и функции (function). Главным отличием функции
от процедуры является то, что функция возвращает под своим
именем результирующее, вычисленное при исполнении кода функции,
значение, процедура такого значения не возвращает.
Сигнатура (описание заголовка) функции выглядит следующим
образом:
Private|Public Function Имя_Функции(ByVal | ByRef параметры As
Тип_Параметров) As Тип_Результата
Соответственно, сигнатура (описание заголовка) процедуры выглядит
так:
Private|Public Sub Имя_Процедуры(ByVal | ByRef параметры As
Тип)
Ключевые слова Public, Private устанавливают уровень доступа к
методам: или метод доступен только в текущем модуле, форме –
Private, или он доступен глобально, в любой имеющейся структуре –
Public.
Ключевые слова ByRef, ByVal описывают способ передачи входных
параметров: или по ссылке (By Reference) или по значению (By Value).
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
В случае передачи параметра по ссылке (ByRef) компилятор
связывает метод непосредственно с самим значением переменной,
хранящимся в памяти.
В случае передачи параметра по значению (By Value) компилятор
выделяет место в памяти для хранения копии значения переменной,
сама переменная остается неизменной. По умолчанию (то есть при
отсутствии указания на способ передачи параметра) используется
передача параметров по значению (ByVal).
При вызове метода в сигнатуре происходит замена формальных
параметров (их описаний) на конкретные фактические значения или
параметры.
Досрочное завершение методов выполняется специальными
операторами Exit Sub или Exit Function, соответственно.
Остается сказать, что для выдачи вычисленного значения из функции
(говорят: функция возвращает значение) используется ключевое
слово Return:
Return результат вычисления.
Приступим к изучению технологии использования методов в коде
программы.
1. Рассмотрим пример, иллюстрирующий передачу параметров по
ссылке и по значению.
Module Module1
Sub Main()
Dim X As Integer=45
proba1(X)
Console.WriteLine("Переменная вне процедуры = " & X)
proba2(X)
Console.WriteLine("Переменная вне процедуры = " & X)
Console.ReadLine()
End Sub
2. Напишем код процедуры proba1(), входной параметр, для
которой будет передаваться по значению (ByVal), то есть копия
параметра. В ходе выполнении процедуры proba1() к значению
объекта X будет добавляться число 5, другими словами, X
изменяется в процедуре.
Имена формальных и фактических переменных могут быть как
одинаковыми, так и разными. Это ни на что не влияет.
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Sub proba1(ByVal X As Integer)
X += 5
Console.WriteLine("Переменная, переданная по значению, в процедуре
= " & X)
End Sub
3. Напишем процедуру proba2(), в которую входной параметр будет
передавать по ссылке (ByRef), то есть, обеспечен доступ
непосредственно к самой переменной X. Пусть процедура
proba2() так же изменяет значение X, увеличивая его на 5.
Sub proba2(ByRef X As Integer)
X += 5
Console.WriteLine("Переменная, переданная по ссылке, в процедуре =
" & X)
End Sub
End Module
4. Соберите консольное приложение и запустите его на
исполнение. Убедитесь в том, что передача параметров по
ссылке и по значению имеет различные последствия для самих
переменных.
5. Тот же эффект наблюдается для любых типов данных,
например, для строк. Рассмотрим этот случай:
Module
Module1
Sub Main()
Dim S As
String
S="Основная
строка"
proba1(S)
Console.WriteLine("Переменная вне процедуры = " & S)
proba2(S)
Console.WriteLine("Переменная вне процедуры = " & S)
Console.ReadLine()
End Sub
Sub proba1(ByVal S As String)
S = "Измененная строка"
Console.WriteLine("При передаче строки по значению: " & S)
End Sub
Sub proba2(ByRef S As String)
S = "Измененная строка"
Console.WriteLine("При передаче строки по ссылке: " & S)
End Sub
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
End Module
6. Теперь рассмотрим синтаксис описания функции и ее вызов в
коде основной программы на классическом примере нахождения
корней квадратного уравнения.
Функция для вычисления количества корней квадратного уравнения и
значений этих корней может выглядеть, например, так:
Public Function Roots(ByVal A As Double, ByVal B As Double, ByVal C As
Double, ByRef X1 As Double, ByRef X2 As Double) As Integer
Dim D As Double
If A = 0 Then
Return 0
Else
D=B*B-4*A*C
If D > 0 Then ' решений два
Return 2
X1 = (-B + System.Math.Sqrt(D)) / (2 * A)
X2 = (-B - System.Math.Sqrt(D)) / (2 * A)
ElseIf D = 0 Then ' решений одно
Return 1
X1 = -B / (2 * A)
Else ' решений нет
Return 0
End If
End If
End Function
Обратите внимание на различные способы передачи входных
параметров в функцию Roots: значения коэффициентов не должны
изменяться, поэтому они передаются по значению (ByVal), а корни
уравнения вычисляются, переменные для их значений передаются в
функцию по ссылке (ByRef).
7. Пример обращения к функции напишем следующий:
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Sub Main()
Dim A, B, C, X1, X2 As Double, nSol
As Integer
Console.WriteLine("Введите значение
A")
A = Console.ReadLine
Console.WriteLine("Введите значение
B")
B = Console.ReadLine
Console.WriteLine("Введите значение
C")
C = Console.ReadLine
nSol = Roots(A, B, C, X1, X2)
If nSol = 0 Then
Console.WriteLine("Решений нет")
ElseIf nSol = 1 Then
Console.WriteLine("X1= " & X1)
Else
Console.WriteLine("X1= " & X1 & "X2=
" & X2)
End If
Console.ReadLine()
End Sub
Воспользуемся текущим примером, чтобы ввести понятие
«импортирование пространств имен». Вы должны были обратить
внимание на вызов стандартной математической функции для
вычисления корня квадратного SQRT(). Функция находится в
пространстве имен System.Math, которое можно было заранее
импортировать в проект, то есть сделать доступным следующим
оператором, написанным до кода всех процедур:
Impotrs System Math
Теперь к функции SQRT() можно обращаться просто по имени,
например, X1 = (-B + Sqrt(D)) / (2 * A). Самостоятельно внесите
соответствующие изменения в код функции и снова протестируйте
приложение.
Пространства имен можно перечислять через запятую, используя
одно ключевое слово Imports.
Самостоятельно
Пусть требуется создать столбец текстовых строк фиксированной
ширины. Например, для оформления вывода текста в элементах
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
управления ListBox, ComboBox или просто для вывода в окне консоли
или для печати.
Другими словами, напишите и протестируйте в различных
практических случаях метод, который дополняет строки текстового
массива пробелами в соответствии с самой длинной строкой в
массиве. Метод может быть реализован как функция, или как
процедура, по-вашему, усмотрению.
Необходимо предусмотреть возможность указания, с какой из сторон
(слева или справа) строки будут дополняться пробелами. Для этого
вам необходимо иметь в проектируемом методе соответствующий
входной параметр, скорее всего, переменную логического типа
(Boolean).
Для решения задачи можно использовать методы класса System.String
PadLeft или PadRight, дополняющие строку пробелами слева или
справа, соответственно, до указанного размера, который является
входным параметром метода.
Поскольку, пока, у вас нет еще достаточного опыта написания
процедур и функций, этот пример начнем рассматривать вместе, но
тестирование метода вы выполните самостоятельно.
В листинге ниже представлена процедура, позволяющая выполнять
перечисленные действия. Используйте ее для построения интерфейса
консоли или Windows приложения.
Private Sub PadString(ByVal strings() As String, ByVal padLeft As
Boolean)
'Определение максимальной длины строки в массиве
Dim MaxLength As Integer = 0
Dim str As String
For Each str In strings
If str.Length > MaxLength Then MaxLength = str.Length
Next
'Дополнение всех строк массива до максимальной длины.
'Цикл For..Next здесь не годится, потому что допускает только чтение,
'а нам нужно изменять строки
Dim i As Integer
For i = 0 To strings.GetUpperBound(0) - 1
If padLeft Then
strings(i) = strings(i).PadLeft(MaxLength)
Else
strings(i) = strings(i).PadRight(MaxLength)
End If
Next
End Sub
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Пример тестирования метода приведен ниже. Если вы воспользуетесь
указанной
процедурой
тестирования,
попробуйте
изменить
соответствие элементов массива, применив любой алгоритм.
Sub Main()
Dim Fruits() As String = {"яблоки", "манго", "бананы", "апельсины"}
Dim Colors() As String = {"красный", "желтый", "оранжевый", "зеленый"}
PadStrings(Fruits, True)
PadStrings(Colors, False)
Dim i As Integer
For i = 0 To
Fruits.GetUpperBound(0) - 1
Console.WriteLine(Fruits(i) & " " &
Colors(i))
Next
Console.ReadLine()
End Sub
Задание 11. Обработка даты и времени
Задача
Получить текущую дату и время. Выполнить математические действия
над датами и интервалами времени.
Решение
Использовать
объекты
классов
или
структур
System.Data,
System.DateTime, System.TimeSpan, их свойства и методы.
Обсуждение
Для работы с информацией о дате и времени .NET предоставляет
структуры System.DateTime (хранит дату и время, например,
20.01.2006 12:00:00) и System.TimeSpan (хранит интервал времени,
например 3 часа), а также класс System.Date. При объявлении
переменных формата дата/время вы можете использовать оба типа
данных (DateTime и Date), как например, в листинге ниже. Объекты
типа TimeSpan удобно использовать при вычислениях с датами.
Для определения текущих значений даты и времени можно
использовать методы Now и ToDay, которые возвращают значение
типа Date, содержащее текущие дату и системное время. Этими
методами располагает, как DateTime, так и Date. Рассмотрим на
примере определение текущей даты и времени:
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Sub Main()
Dim d As Date
Console.WriteLine(d.Today)
Console.WriteLine(d.Now)
d = d.Today.AddDays(30)
Console.WriteLine(d)
Dim d1 As DateTime
Console.WriteLine(d1.Today)
Console.WriteLine(d1.Now)
Console.WriteLine(d1.Today.AddYears(1))
Console.ReadLine()
End Sub
С помощью символа (#) происходит непосредственное присваивание
значения даты. Вычисления с датами удобно выполнять методами
Add или Subtract (оба типа имеют аналогичные методы). Результат
метода Subtract удобно присвоить не просто числовому объекту, а
объекту типа TimeSpan, который в свою очередь, имеет ряд свойств и
методов.
Sub Main()
Dim d As Date = #10/10/2005#
Console.WriteLine(d)
Dim dd As TimeSpan
dd = DateTime.Now.Subtract(d)
Console.WriteLine(dd.Days)
Console.ReadLine()
End Sub
При работе с датами нельзя использовать операторы сравнения (< и
>). Однако вы можете получить число, представляющее интервал
TimeSpan,
используя
свойства,
TotalHourse,
TotalMinutes,
TotalMilliseconds или Ticks, которое может участвовать в операции
сравнения как операнд.
Самостоятельно
Создайте приложение, позволяющее определять, на какой день
недели выпадает конкретная дата, является ли указанный год
високосным и сколько дней содержится в конкретном месяце.
Используйте пространство имен System.Globalization, в котором
определены классы, поддерживающие календарные даты, связанные
с региональными стандартами. В число этих классов входят классы
GregorianCalendar
(западный
стандарт),
HebrewCalendar,
JulianCalendar, JapaneseСalendar и так далее. В этих классах
инкапсулирован ряд методов, которые позволят вам решить
поставленную задачу:
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
 GetDaysInMonth – возвращает число дней в конкретном
месяце;
 GetDaysInYear – возвращает число дней в конкретном году;
 IsLeapYear – возвращает True, если конкретный год является
високосным и так далее.
Пример объявления объекта класса GregorianCalendar и обращения к
его функциям представлен ниже:
Module Module1
Sub Main()
Dim calendar As New System.Globalization.GregorianCalendar
Console.WriteLine ("Количество дней в феврале 2006 года " &
calendar.GetDaysInMonth(2006, 2, 0))
Console.ReadLine()
End Sub
End Module
Download