[C++] 조건이 짧아서 x가 네 개의 숫자가 아닌지 확인하십시오.


Answers

정수가 주어진 정수 집합에 있는지 알아 std::set 을 사용하십시오.

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

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

if 문에 대한 조건을 단축 할 수있는 방법이 있습니까?

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

나는 이런 종류의 것을 생각하고있다.

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

그러나 나는 그것을 시도하고 그것이 작동하지 않습니다. 먼 길을 모두 써야합니까?




매크로의 사용은 매크로가 매우 강력하고 부적절하게 생성 된 경우 좌절하는 능력이 있기 때문에 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;
}

매크로는 사용하고자하는 곳에 포함 된 헤더 파일에 있어야합니다. 다른 곳에서 코드에서 'unused'라는 변수를 이미 사용하고 있거나이 매크로를 사용하여 정수가 아닌 다른 변수를 비교하려고하면 코드가 컴파일되지 않습니다. 필요한 경우 다른 유형의 데이터를 처리하도록 매크로를 확장 할 수 있다고 확신합니다.

모든 입력을 대괄호로 묶어 연산 순서를 보존하고 비교 전에 변수에 값을 저장하여 CPU 집약적 인 코드가 여러 번 실행되는 것을 방지합니다.




숫자가 "1,2,3,4"가 아니고 대신 임의의 난수의 임의의 정수인 경우 해당 숫자를 데이터 구조 (예 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();
}



여기 내 variadic 템플릿을 사용하여 솔루션입니다. 런타임 성능은 수동으로 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;
}



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

int x;

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



완전성을 위해 스위치를 사용하여 제안합니다.

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

이것은 매우 장황하지만, x 한 번만 평가하고 (표현식 인 경우) 아마 모든 솔루션의 가장 효율적인 코드를 생성합니다.




이건 어때?

#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;
}

불행히도 파서는 연산자의 인수로 initializer_list 를 갖고 싶어하지 않으므로 두 번째 해법에서는 std::vector<int> 를 제거 할 수 없습니다.




이 조건을 반복해서 반복하지 않으려면 매크로를 사용하십시오.

#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;
}