Приветствую Вас ГостьСреда, 15.05.2024, 02:20

Каталог статей


Стив Макконнелл "Совершенный код". Табличные методы

Табличный метод — это схема, позволяющая искать информацию в таблице, а не использовать для этого логические выражения, такие как if и case.

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

if ( ( ( ‘a’ <= inputChar ) && ( inputChar <= ‘z’ ) ) ||
   ( ( ‘A’ <= inputChar ) && ( inputChar <= ‘Z’ ) ) ) {
   charType = CharacterType.Letter;
}
else if ( ( inputChar == ‘ ‘ ) || ( inputChar == ‘,’ ) ||
   ( inputChar == ‘.’ ) || ( inputChar == ‘!’ ) || ( inputChar == ‘(‘ ) ||
   ( inputChar == ‘)’ ) || ( inputChar == ‘:’ ) || ( inputChar == ‘;’ ) ||
   ( inputChar == ‘?’ ) || ( inputChar == ‘-’ ) ) {
   charType = CharacterType.Punctuation;
}
else if ( ( ‘0’ <= inputChar ) && ( inputChar <= ‘9’ ) ) {
   charType = CharacterType.Digit;
}

Если бы вместо этого фрагмента вы использовали таблицу подстановки, то поместили бы тип каждого элемента в массив и обращались бы к нему по коду символа. Сложный фрагмент кода, представленный выше, заменялся бы на такое выражение:

charType = charTypeTable[ inputChar ];

Этот фрагмент предполагает, что массив charTypeTable был заранее заполнен

Способы, применяются для поиска записи в таблице:

  • прямой доступ;
  • индексированный доступ;
  • ступенчатый доступ.

Таблицы с прямым доступом

Таблицы с прямым доступом предназначены для замены более сложных логических структур

Допустим, вы хотите получить число дней в месяце (для простоты забудем о високосных годах). Разумеется, создание большого условия if — неуклюжий способ решения этой проблемы:

If ( month = 1 ) Then
   days = 31
ElseIf ( month = 2 ) Then
   days = 28
ElseIf ( month = 3 ) Then
   days = 31
ElseIf ( month = 4 ) Then
   days = 30
ElseIf ( month = 5 ) Then
   days = 31
ElseIf ( month = 6 ) Then
   days = 30
ElseIf ( month = 7 ) Then
   days = 31
ElseIf ( month = 8 ) Then
   days = 31
ElseIf ( month = 9 ) Then
   days = 30
ElseIf ( month = 10 ) Then
   days = 31
ElseIf ( month = 11 ) Then
   days = 30
ElseIf ( month = 12 ) Then
   days = 31
End If

Более простой и удобный для модификации способ выполнения тех же самых действий — разместить данные в таблице. В Visual Basic первым делом нужно заполнить таблицу:

‘ Инициализируем таблицу данными о количестве дней в месяцах.
Dim daysPerMonth() As Integer = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }

‘ Получаем количество дней
days = daysPerMonth( month-1 )

Если вы хотите учитывать високосные годы в этой версии табличного поиска, код все еще будет простым. Допустим, LeapYearIndex() возвращает 0 или 1:

days = daysPerMonth( month-1, LeapYearIndex() )

Если бы в версии с выражением if тоже учитывались високосные годы, то длинная строка условий if еще более усложнилась бы.

Таблицы с индексированным доступом

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

Допустим, вы заведуете складом, и у вас около 100 наименований товара. Далее предположим, что каждый товар имеет четырехзначный номер в диапазоне от 0000 до 9999. В этом случае, если вы захотите задействовать номер товара в качестве ключа для прямого доступа к таблице, описывающей какой-то признак каждого товара, вам придется создать индексный массив с 10 000 записей (от 0 до 9999). Этот массив в основном будет пустым за исключением 100 элементов, соответствующих номерам товаров на вашем складе.

Основное преимущество использования индексов - это экономия памяти, так как создание массива с большим количеством пустых ячеек потребует гораздо меньше места, чем создание самой таблицы поиска с большим количеством пустых ячеек.

Таблицы со ступенчатым доступом

Еще один способ табличного доступа — ступенчатый метод. Этот метод не такой прямой, как индексная структура, но позволяет не терять такого большого объема памяти.
Основная идея ступенчатой структуры в том, что записи в таблице соответствуют некоторому диапазону данных, а не отдельным элементам

Например, если вы пишете аттестационную программу, диапазон оценки «B» может быть в пределах 75–90%. Вот список оценок, которые вам однажды, возможно, придется запрограммировать:
≥ 90.0% A
< 90.0% B
< 75.0% C
< 65.0% D
< 50.0% F

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

Пример ступенчатого поиска в таблице (Visual Basic)
‘ Подготавливаем данные для таблицы оценок.
Dim rangeLimit() As Double = { 50.0, 65.0, 75.0, 90.0, 100.0 }
Dim grade() As String = { ”F”, “D”, “C”, “B”, “A” }
maxGradeLevel = grade.Length – 1
...
’ Присваиваем оценки, основываясь на количестве баллов, набранных студентом.
gradeLevel = 0
studentGrade = “A”
While ( ( studentGrade = “A” ) and ( gradeLevel < maxGradeLevel ) )
   If ( studentScore < rangeLimit( gradeLevel ) ) Then
      studentGrade = grade( gradeLevel )
   End If
   gradeLevel = gradeLevel + 1
Wend

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

Не ошибитесь с операциями < или <=! Убедитесь, что при значениях, попадающих в верхний диапазон, цикл корректно завершается, а также что границы интервалов обрабатываются правильно.

 

 

Категория: Стив Макконнелл "Совершенный код" | Добавил: leshic (15.11.2021)
Просмотров: 306 | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email *:
Код *:
Вход на сайт
Поиск
Категории раздела
Стив Макконнелл "Совершенный код" [20]
Стив Макконнелл "Совершенный код"
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0