缩短条件以检查x不是四个数字中的任何一个

时间:2016-01-13 05:54:21

标签: c++ if-statement

有没有办法缩短此if声明的条件?

int x;
if (x != 3 && x != 8 && x != 87 && x != 9){
  SomeStuff();
}

我想的是这样的事情:

if (x != 3, 8, 87, 9) {}

但是我试过了,但它不起作用。我是否只需要将其全部写出来?

8 个答案:

答案 0 :(得分:43)

如果您想知道整数是否在给定的整数集中,请使用std::set

std::set<int> accept { 1, 4, 6, 8, 255, 42 };
int x = 1;

if (!accept.count(x))
{
    // ...
}

答案 1 :(得分:31)

为了完整起见,我会提供一个开关:

switch (x) {
    case 1:
    case 2:
    case 37:
    case 42:
        break;
    default:
        SomeStuff();
        break;
}

虽然这非常详细,但它只评估x一次(如果它是一个表达式),并且可能生成任何解决方案的最有效代码。

答案 2 :(得分:28)

这是我使用可变参数模板的解决方案。运行时性能与手动编写x != 3 && x != 8 && x != 87 && x != 9一样高效。

template <class T, class U>
bool not_equal(const T& t, const U& u) {
  return t != u;
}

template <class T, class U, class... Vs>
bool not_equal(const T& t, const U& u, const Vs... vs) {
  return t != u && not_equal(t, vs...);
}

int main() {
  std::cout << not_equal( 3, 3, 8, 87, 9) << std::endl;
  std::cout << not_equal( 8, 3, 8, 87, 9) << std::endl;
  std::cout << not_equal(87, 3, 8, 87, 9) << std::endl;
  std::cout << not_equal( 9, 3, 8, 87, 9) << std::endl;
  std::cout << not_equal(10, 3, 8, 87, 9) << std::endl;
}

答案 3 :(得分:14)

这个怎么样:

#include <iostream>
#include <initializer_list>
#include <algorithm>

template <typename T>
bool in(const T t, const std::initializer_list<T> & l) {
    return std::find(l.begin(), l.end(), t) != l.end();
}

int main() {
  std::cout << !in(3, {3, 8, 87, 9}) << std::endl;
  std::cout << !in(87, {3, 8, 87, 9}) << std::endl;
  std::cout << !in(10, {3, 8, 87, 9}) << std::endl;
}

或重载operator!=

template<typename T>
bool operator!=(const T t, const std::vector<T> & l) {
    return std::find(l.begin(), l.end(), t) == l.end();
}

int main() {
  std::cout << ( 3!=std::vector<int>{ 3, 8, 87, 9}) << std::endl;
  std::cout << ( 8!=std::vector<int>{ 3, 8, 87, 9}) << std::endl;
  std::cout << (10!=std::vector<int>{ 3, 8, 87, 9}) << std::endl;
}

不幸的是目前parsers do not like to have initializer_list as argument of operators,所以在第二个解决方案中无法摆脱std::vector<int>

答案 4 :(得分:5)

如果您不想一遍又一遍地重复此条件,请使用宏。

#include <iostream>

#define isTRUE(x, a, b, c, d)  ( x != a && x != b && x != c && x != d ) 

int main() 
{
    int x(2);
    std::cout << isTRUE(x,3,8,87,9) << std::endl;

    if ( isTRUE(x,3,8,87,9) ){
        // SomeStuff();
    }
    return 0;
}

答案 5 :(得分:3)

如果数字不是&#34; 1,2,3,4&#34;而是随机数的随机整数,然后你可以将这些数字放在数据结构中(例如std::vector),然后使用循环遍历该数组(如下所示,std :: find是一个现成的选项。)

例如:

#include <algorithm>

int x;
std::vector<int> checknums;
// fill the vector with your numbers to check x against

if (std::find(checknums.begin(), checknums.end(), x) != checknums.end()){
    DoStuff();
}

答案 6 :(得分:3)

int A[]={3, 8, 87, 9};

int x;

if (std::find(A, A+4, x)==A+4) SomeStuff();

答案 7 :(得分:3)

请注意,许多C ++程序员都非常不喜欢使用宏,因为宏非常强大,并且如果创建不当,就有可能令人沮丧。但是,如果正确和智能地创建和使用它们可以节省大量时间。我没有看到另一种方法来获得所请求的语法和代码空间,每次比较类似于您请求的内容,而不会影响程序使用的效率,代码空间或内存。您的目标是拥有一条捷径,此处提供的大多数其他解决方案都比您最初想要缩短的时间长。假设您正在比较整数:

,下面是安全地执行此操作的宏
#pragma once
int unused;
#define IFNOTIN2(x, a, b) \
  if (unused = (x) && unused != (a) && unused != (b))
#define IFNOTIN3(x, a, b, c) \
  if (unused = (x) && unused != (a) && unused != (b) && unused != (c))
#define IFNOTIN4(x, a, b, c, d) \
  if (unused = (x) && unused != (a) && unused != (b) && unused != (c) && unused != (d))
#define IFNOTIN5(x, a, b, c, d, e) \
  if (unused = (x) && unused != (a) && unused != (b) && unused != (c) && unused != (d) && unused != (e))

以下是使用上述宏之一的经过测试的示例:

#include <iostream>
#include "macros.h"

int main () {
  std::cout << "Hello World\n";

  for (int i = 0; i < 100; i ++) {
    std::cout << i << ": ";
    IFNOTIN4 (i, 7, 17, 32, 87) {
      std::cout << "PASSED\n";
    } else {
      std::cout << "FAILED\n";
    }
  }
  std::cin.get();

  return 0;
}

请注意,宏应该放在一个包含在您需要使用它们的位置的头文件中。如果您已经使用名为&#39; unused&#39;的变量,则代码将无法编译。在其他地方的代码中或尝试使用这些宏来比较整数以外的东西。我确定你可以扩展宏来处理其他类型的数据,如果有必要的话。

通过在所有输入周围使用括号来保留操作顺序,并在比较之前将值保存到变量中,以防止多次执行CPU密集型代码。