将变量与多个值进行比较的最有效方法?

新手上路,请多包涵

在我的程序中有几次,我不得不检查一个变量是否是许多选项之一。例如

if (num = (<1 or 2 or 3>)) { DO STUFF }

我已经搞砸了“或”,但似乎没有什么是正确的。我试过了

if (num == (1 || 2 || 3))

但它什么也没做。

我想方便地区分几个组。例如

if (num = (1,2,3))

else if (num = (4,5,6))

else if (num = (7,8,9))

原文由 Matt Reynolds 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 709
2 个回答

如果您要检查的值足够小,您可以为您寻找的值创建一个位掩码,然后检查该位是否被设置。

假设,您关心几个组。

 static const unsigned values_group_1 = (1 << 1) | (1 << 2) | (1 << 3);
static const unsigned values_group_2 = (1 << 4) | (1 << 5) | (1 << 6);
static const unsigned values_group_3 = (1 << 7) | (1 << 8) | (1 << 9);
if ((1 << value_to_check) & values_group_1) {
  // You found a match for group 1
}
if ((1 << value_to_check) & values_group_2) {
  // You found a match for group 2
}
if ((1 << value_to_check) & values_group_3) {
  // You found a match for group 3
}

这种方法最适用于不超过 CPU 喜欢使用的自然大小的值。在现代,这通常是 64,但可能会根据您的环境的具体情况而有所不同。

原文由 Eric Johnson 发布,翻译遵循 CC BY-SA 3.0 许可协议

这是 C++11 中的一种方法,使用 std::initializer_list

 #include <algorithm>
#include <initializer_list>

template <typename T>
bool is_in(const T& v, std::initializer_list<T> lst)
{
    return std::find(std::begin(lst), std::end(lst), v) != std::end(lst);
}

有了它,你可以这样做:

 if (is_in(num, {1, 2, 3})) { DO STUFF }

尽管不与内置类型一起使用时,它不是很有效。 int 可以正常工作,但如果你比较 std::string 变量,例如,生成的代码很糟糕。

但是,在 C++17 中,您可以改用更有效的解决方案,该解决方案适用于任何类型:

 template<typename First, typename ... T>
bool is_in(First &&first, T && ... t)
{
    return ((first == t) || ...);
}

// ...

// s1, s2, s3, s4 are strings.
if (is_in(s1, s2, s3, s4)) // ...

C++11 版本在这里效率非常低,而这个版本应该产生与手写比较相同的代码。

原文由 Nikos C. 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题