Табличный метод
Табличный метод — это схема, позволяющая искать информацию в таблице, а не использовать для этого логические выражения, такие как if и case. Практически все, что вы можете выбирать посредством логических операторов, можно выбирать, применяя таблицы. В простых случаях логические выражения проще и понятней. Но при усложнении логических построений таблицы становятся все привлекательнее.
Рассмотрим пример определения количества дней в месяце. Допустим, вы хотите получить число дней в месяце (для простоты забудем о високосных годах). Разумеется, создание большого условия if — неуклюжий способ решения этой проблемы:
if (month == 1) days = 31;
else if (month == 2) days = 28;
else if (month == 3) days = 31;
else if (month == 4) days = 30;
else if (month == 5) days = 31;
else if (month == 6) days = 30;
else if (month == 7) days = 31;
else if (month == 8) days = 31;
else if (month == 9) days = 30;
else if (month == 10) days = 31;
else if (month == 11) days = 30;
else if (month == 12) days = 31;Более простой и удобный для модификации способ выполнения тех же самых действий — разместить данные в таблице (в данном случае одномерном массиве):
int daysPerMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
days = daysPerMonth[month-1];Определение количества дней в месяце — удобный пример, так как переменную
month можно использовать для поиска записи в таблице.
Рассмотрим другой пример со ставками медицинского страхования, которые варьируются в зависимости от возраста, пола, семейного положения и от того, курит ли страхователь. Если бы вы писали для этих ставок логическую управляющую структуру, то получилось бы нечто вроде этого:
if ( gender == Gender.Female ) {
if ( maritalStatus == MaritalStatus.Single ) {
if ( smokingStatus == SmokingStatus.NonSmoking ) {
if ( age < 18 ) {
rate = 200.00;
}
else if ( age == 18 ) {
rate = 250.00;
}
else if ( age == 19 ) {
rate = 300.00;
}
...
else if ( 65 < age ) {
rate = 450.00;
}
else {
if ( age < 18 ) {
rate = 250.00;
}
else if ( age == 18 ) {
rate = 300.00;
}
else if ( age == 19 ) {
rate = 350.00;
}
...
else if ( 65 < age ) {
rate = 575.00;
}
}
else if ( maritalStatus == MaritalStatus.Married )
...
}Эта сокращенная версия логической структуры — хорошая иллюстрация того, насколько сложной может получиться программа. Она не учитывает замужних женщин, всех мужчин и большинства возрастов между 18 и 65 годами. Вы можете вообразить, насколько сложной станет эта структура, если запрограммировать всю таблицу ставок.
Вы можете сказать: «Да, но почему вы проверяете каждый возраст? Почему бы не поместить ставку для каждого возраста в массив?» Хороший вопрос, и одним из очевидных усовершенствований будет размещение ставок для каждого возраста в отдельных массивах.
Однако лучшее решение — создать массив ставок не только для каждого возраста, но вообще для всех факторов.
enum SmokingStatus{
Smoking,
NonSmoking
};
enum Gender{
Male,
Female
};
enum MaritalStatus{
Single,
Married
};
const int max_age = 100;
int main()
{
double rateTable[2][2][2][max_age];
// заполнение массива rateTeable
double rate = rateTable[Smoking][Male][Married][43];
}Сложная логическая структура, показанная ранее, заменяется простым выражением. Основное преимущество этого подхода — в замене сложной логики табличным поиском. Такой код удобней читать и проще изменять.
При применении табличных методов перед вами стоят два основных вопроса. Во-первых, вам надо решить, как будет выполняться поиск записей в таблице. Вы можете использовать какие-либо данные для прямого доступа к таблице. Так, если вам нужно систематизировать данные по месяцам, то выбор ключа для таблицы месяцев очевиден. Вы можете использовать массив с индексом от 1 до 12.
Другие данные затруднительно использовать для прямого поиска табличной записи. Так, для классификации информации по серии и номеру паспорта вы не сможете использовать этот номер в качестве ключа непосредственно, если, конечно, вы не собираетесь хранить в таблице огромное количество записей. Вам понадобится более сложный подход. Вот какие способы, применяются для поиска записи в таблице:
- прямой доступ;
- индексированный доступ;
- ступенчатый доступ.
Второй вопрос, который нужно решить при использовании табличных
методов: что хранить в таблице. Иногда результатом поиска в таблице
являются данные — тогда можно хранить в таблице сами данные. Если
же результатом поиска является действие, можно хранить ссылку на метод, выполняющий это действие. В каждом из этих случаев таблицы усложняются.