在 IF 条件下进行多次检查
alternate to multiple checks in IF condition
有没有其他方法可以重写这段代码?
if(i == 0 || i == 4 || i == 6 || i == 8 || i == 9 || i == 19 || i == 198 || i == 41 )
{
// do something
}
在 if 条件下忽略此多次检查的另一种方法是什么......我们是否有类似 IN 语句(SQL 查询)的内容C++?..提前谢谢..
通常情况下,编写一个新函数可以非常优雅:
template <typename Range, typename T>
bool contains(Range range, T element) {
return std::find(std::begin(range), std::end(range), element) != std::end(range);
}
template <typename T>
bool contains(std::initializer_list<T> range, T element) {
return contains<std::vector<int>>(range, element);
}
我选择了基于范围的方法,但您也可以提供采用开始/结束迭代器的重载。另外,请随意在实现中使用std::find
以外的其他内容。
(我们真的必须超载std::initializer_list
吗?似乎很奇怪,我们无法推断它。
现在我们可以写:
if (contains({1, 2, 3, 4, 5}, 3))
一个简单的开关盒是最易读的:
switch (i) {
case 0:
case 4:
case 6:
case 8:
case 9:
case 19:
case 198:
case 41:
// DO THINGS
break;
default:
// OTHERS
}
使用静态常量无序集合:
static const std::unordered_set<int> my = { 1 , 1 , 2 , 3 , 5 , 8 , 13 } ;
auto find = my.find( 8 ) ;
if( find != my.end() )
{
cout << "found:" << *find << endl ;
}
搜索复杂度平均为 O(1)。
并且应该是线程安全的。
好吧,在 C 中(当然还有C++),您可以:
switch(i)
{
case 0:
case 4:
case 6:
case 8:
case 9:
case 19:
case 198:
case 41: // do something
break;
}
当然,编译器将生成与原始 if 几乎相同的代码,但也许这看起来更清晰?
编写这样的语句是一个错误
if(i = 0 || i = 4 || i = 6 || i = 8 || i = 9 || i = 19 || i = 198 || i = 41 )
您需要 == 运算符进行比较。现在,既然您正在比较一种类型的值与多种类型的值。使用开关语句是更好的解决方案。快乐编码
static const int options[] = {0, 4, 6, 8, 9, 19, 198, 41};
if (std::find(std::begin(options), std::end(options), i) != options.end()) {
// do something
}
如评论中所述,只要您保持选项排序,就可以使用它
static const int options[] = {0, 4, 6, 8, 9, 19, 198, 41};
if (std::binary_search(std::begin(options), std::end(options), i)) {
// do something
}
这应该更快。
对于小数组,我认为选择哪种变体并不重要。
将初始值设定项列表(或向量)与 std::any_of 一起使用:
static const auto accepted = { 0, 4, 6, 8, 9, 19, 198, 41 };
if( std::any_of(std::begin(accepted), std::end(accepted),
[&i](int x) { return i == x; }) {
// do something
}
(这是@JosephMansfield在评论中提出的)
编辑:这可以通过对整数值重新排序来优化,首先针对命中率最高的值进行优化。
您可以使用 STL MAP ...试试这个..
#include<cstdio>
#include<map>
using namespace std;
map<int,int>mp;
int main()
{
int i;
mp[0]=mp[4]=mp[6]=mp[8]=mp[9]=mp[19]=mp[198]=mp[41]=1;
scanf("%d",&i);
if(mp[i])
{
//do something
}
return 0;
}
使用像这样的简短固定列表,您可以查找一个整数n
,以便所有元素在除以 n
时具有不同的余数。例如,n = 14
在这里可以解决问题,因为余数mod 14
是 0、4、6、8、9、5、2 和 13。所以你可以这样做:
static const int remainder_table[14] = {
0, 0, 198, 0, 4, 19, 6, 0, 8, 9, 10, 0, 0, 41
} ;
if (remainder_table[i % 14] == i) {
// do something
}
警告:这不一定比原始if
语句更快!这取决于硬件划分的速度和编译器的优化能力。
如果你想将i
与常量进行比较 - 这是在合规时已知的,你可以使用TMP。
namespace detail
{
template <int ...Args>
struct CompFunc;
template <int num, int ...Args>
struct CompFunc<num, Args...>
{
static constexpr bool f(int i)
{
return (i == num) || CompFunc<Args...>::f(i);
}
};
template <>
struct CompFunc<>
{
static constexpr bool f(int i)
{
return false;
}
};
}
template <int ...Args>
constexpr bool any_of_const(int i)
{
return detail::CompFunc<Args...>::f(i);
}
和
if (any_of_const<0, 4, 6, 8, 9, 19, 198, 41>(i))
{
...
}
(现场示例)
- 检查一个类型是否直接派生自"enable if"上下文中的另一个类型(是其子类型)
- 简化对两个布尔值的 4 个 if/else 检查
- 获取 if 语句以检查定义的宏
- 尝试使用 indexOf 创建一个 if 语句来检查字符串是否包含字符.有一点麻烦
- 在if条件下,右或左改变值的相等性检查是否有任何区别
- if 语句正在检查什么条件
- 在 c++ 中检查 if 条件中的向量位置范围
- 卡在 if 语句中,以检查列表中的数字
- 如何避免使用多个if-else来检查返回值是否为错误代码?
- 重构使用 if 语句的重复范围检查
- 检查指针是否为null,然后在同一if语句中取消引用它,这样安全吗
- 使用 if if 语句检查 C++ 中的范围
- 在执行其中的代码之前,是否处理了 if 中的所有逻辑 OR 分隔检查?
- 是一个 for 循环,最终甚至不会运行一次,就像调用 if 语句以首先检查大小一样快
- 条件检查:if(x==0) vs. if(!x)
- C++ 简单 if 语句不检查?
- 如何使用嵌套的 if 语句检查字符数组
- 如何使用if语句来检查字符串文字是否是某个单词或短语
- 检查if语句的多个相等/不相等条件
- 检查IF语句中的多个OR操作符