제약을 통한 문제해결 응용력 키우기 훈련 2-1 (데이터 교환)
2022.12.10. 최초 작성
제약을 통한 문제해결 응용력 키우기 훈련 2에서 데이터 교환(swap) 문제에 새로운 변수를 만들지 않는 제약조건을 가지고 문제를 풀어보았다.
이번에는 같은 문제인데 제약조건을 조금 약하게 변경하여 다른 방향으로 접근하려 한다.
새로운 변수를 추가하지는 않지만 두 변수의 자료구조 변경은 허용한다.
이전에는 두 변수가 정수 타입의 int 변수를 유지하고 문제를 풀었지만, 이번에는 반드시 두 변수가 정수 타입을 유지할 필요는 없다. 사실 이것은 엄밀히 말하면 기존의 메모리 공간을 그대로 사용하는 것은 아니다.
파이썬 언어는 정수 타입 int 변수도 객체 타입으로 직접 값을 저장하지 않고 다른 메모리 공간에 있는 데이터를 참조하는 방식이다. a와 b라는 변수는 실제로 데이터가 저장된 메모리의 주소를 기억하는 것이다.
파이썬이 지원하는 튜플이란 자료구조를 활용하면 a와 b의 값을 쉽게 교환할 수 있다.
a = 10
b = 20
print('[교환 전] : a=', a, type(a), id(a), 'b=', b, type(b), id(b))
b, a = a, b
print('[교환 후] : a=', a, type(a), id(a), 'b=', b, type(b), id(b))

type 함수를 통해 a와 b의 클래스 타입을 확인하고, id 함수를 통해 실제로 값이 저장된 메모리 주소를 알 수 있다.
위 코드는 내부에서 정수 a와 b를 튜플로 바꾼 후 값을 교환하고 다시 정수 타입으로 바꿔주는 작업을 한다.
이런 방식의 코드는 파이썬에서 일반적으로 자주 사용되기 때문에 새로운 것이 아니다.
아래는 튜플 자료구조를 사용하지 말고 문자열인 str 자료구조를 이용한 코드이다.
a = 10
b = 20
print('[교환 전] : a=', a, type(a), id(a), 'b=', b, type(b), id(b))
a = str(a)+' '+str(b)
b, a = map(int, a.split())
print('[교환 후] : a=', a, type(a), id(a), 'b=', b, type(b), id(b))
정수 타입인 a와 b를 문자열 타입으로 바꾸어 연결한 후 자른 것을 다시 int 타입으로 바꾸어 b와 a에게 연결하는 구조이다.
이 방식은 b, a = a, b 이렇게 처리하는 것보다 구조적으로 더 복잡하고 코드도 길어지므로 마냥 좋은 방식은 아니다.
그렇지만 기존에 사용하던 도구가 너무 당연해지면 정작 그 도구를 사용할 수 없을 때는 문제를 해결하지 못하거나 굉장히 오래 걸릴 수도 있다.
[결론]
기존에 익숙한 것을 사용하는 것이 더 쉽고 빠르겠지만 그것을 너무 당연하게 생각하지 않아야 한다.
같은 문제를 해결하더라도 나에게 익숙하지 않은 방식에 대해 깊은 고민을 해보는 것을 추천한다.