2013-02-28 3 views
0

У меня есть следующий сценарий:Предпочтительный способ тестирования многих дискретных значений?

variable in {12, 4, 999, ... }: 

Где существует около 100 дискретных значений в списке. Я пишу синтаксический анализатор, чтобы преобразовать его в C++, и единственные способы, которые я могу сделать для этого, - это 100 case-заявлений или 100, если ==

Предпочитаете ли вы другое, или есть круглый лучший способ сделать это?

Я должен уточнить, значения являются постоянными целыми числами. Спасибо

ответ

1

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

Вы можете поместить свои значения в векторе в отсортированном порядке, используя std::lower_bound для точки вставки, а затем использовать std::binary_search для проверки членства, или вы можете поместить свои значения в std::set и получить эту функцию бесплатно (с использованием std::set::find() для тестирование на членство).

Есть незначительные соображения производительности, которые могут сделать любой вариант предпочтительным; профиль и решить для себя.

Второй подход заключается в том, чтобы поместить ваши значения в хэш-таблицу, такую ​​как std::unordered_set (или какой-то статический эквивалент, если ваши значения известны статически).

2

Если максимальное значение любого из ваших дискретных значений является достаточно маленьким, то std::vector<bool> флагов, установленных как true, так и false, в зависимости от того, должна ли эта запись в списке быть довольно оптимальной - при условии, что значения происходят с приблизительно равной вероятностью.

1

Предполагая, что значения являются константами, вы, безусловно, можете использовать оператор switch. Компилятор сделает это довольно эффективно, используя либо подход двоичного типа поиска, либо таблицу [или комбинацию таблицы и двоичного поиска]. Длинный список if-операторов не будет столь же эффективным, если вы не сортируете числа и не используете метод двоичного типа поиска - оператор switch гораздо проще генерировать, так как компилятор будет выбирать наилучший подход, чтобы решить, какие числа в списке, а какие нет.

Если значения не являются константами, то инструкция switch, очевидно, не является решением. Растровое изображение может работать - опять же, в зависимости от фактического диапазона - значений большой диапазон, то это не очень хорошее решение, так как оно будет использовать много памяти [но это, вероятно, один из самых быстрых методов, поскольку это просто случай деления/по модулю с номером 2^n, что можно сделать с помощью простых операторови &, за которыми следует одно чтение памяти].

Смежные вопросы