프로그램을 하다보면, 단순하게 두 가지 상태를 전환하는 문제가 많이 생겨난다. 예를 들어 불을 끄고 키는 것처럼 말이다. 그런데 이러한 상태를 전환하는 간단한 문제에 비교 구문을 이용하지 않고 작성하는 좋은 방법이 있을까?
일반적으로는 아마 다음과 같이 프로그램을 작성할 것이다.
int switch(int flag)
{
if(flag)
return 0;
else
return 1;
}
뭐 위의 예제는 0,1을 전환하는 함수가 되는데, 조건하고 반환하는 값만 바꾸면 다른 값들의 전환도 가능할 것이다.
이제 생각을 전환해 보기위해서 잠시 swap함수에 대해서 살펴보자. swap함수는 잘 알고 있는 것처럼 두 값을 바꾸어주는 함수이다. 일반적으로는 다음과 같이 작성한다.
void swap(int& a, int& b)
{
int temp;
temp = a;
a = b;
b = temp;
}
그런데 임시 변수를 사용하지 않고 swap함수를 작성할 수 있을까? 불가능한가? 물론 가능하닌깐 물어본 것이다. 먼저 프로그램을 작성해 보면 다음과 같을 것이다.
void swap(int& a, int& b)
{
b = a + b;
a = b - a;
b = b - a;
}
위의 이상한 수식은 무엇인가. 만약 두 가지 원소를 가지고 있는 집합 A를 생각해 보자. 집합 A가 {a, b}라는 두가지 원소(여기서는 그냥 정수라고 하자)를 가질 때 원소가 a뿐인 집합 B로 차집합을 하면 당연히 원소 b만 가지는 새로운 집합이 나오고 원소가 b뿐인 집합 B로 차집합을 하면 마찬가지로 원소 a만 가지는 새로운 집합이 나올 것이다. 아하! 무언가 떠오르지 않는가? a,b 원소를 가지는 집합을 a+b라고 하고 a를 가지는 집합으로 차집합 (a+b) - a를 하면 원소 b를 가지는 집합이 나오고 (a+b) - b를 하면 원소 a를 가지는 집합이 나온다. 두 가지 상태가 전환되는 것을 알 수 있다.
그러면 이 것을 아까 위의 switch함수에 적용하면 두가지 원소가 0, 1이므로 다음과 같은 함수가 될 것이다.
int switch(int flag)
{
flag = 1 - flag;
return flag;
}
두 원소의 합은 0 + 1이므로 1이고 원소를 하나만 가지는 부분 집합이 flag이므로 flag가 0이면 1이 그 다음에는 1이 들어올 것이므로 flag는 0이 된다.
백승지
flag가 0과 1만 가능하다면 bool flag로 놓고 flag=!flag; 가 더 간단하지 않을까요?
kwanny
swap의 경우 int에 한정해서 void swap(int &a, int &b) { a^=b^=a^=b; } 이런 방법도 있져 ^^;
2004/01/04일에 네이버 블로그에 써놓았던 글을 가져옴.
답글삭제