본문 바로가기

Note/PS (Algorithm)

[알고리즘] PS 및 알고리즘 코드 작성 언어별 비교

프로그램 개발 또는 특정 프레임워크 사용이 아니라 Problem Solving 즉, 알고리즘 및 코딩 테스트 문제 해결을 위해서는 다양한 프로그래밍 언어를 고려해볼 수 있습니다. 그 중에서 대표적으로 많이 사용되는 언어 세 가지를 비교해보고 특징을 살펴보고자 합니다.

여기서 다룰 세 가지의 언어는 당연하게도 C++, Java, Python이 되겠습니다. 저는 주로 C++ > Python >>> Java 의 순으로 보통 사용하지만 요즘은 Python 리스트와 문자열의 압도적인 편리함 때문에 점차 그 사용빈도가 C++과 가까워지고 있습니다. Java 는 입출력 작성부터 코드가 길어지고 역량이 부족한 저에게는 귀찮고 불편한 존재라고 느껴져서.. 정말 가끔 Java 공부를 위해서 사용하곤 합니다. 그럼에도 각 언어가 가지는 장단점과 특징이 있기에 본 포스팅에서 정리하고자 합니다. 또한 요즘은 대부분의 알고리즘 대회 및 코딩 테스트에서 언어별로 수행 시간 제한을 따로 책정하기 때문에 시간 효율과 메모리 효율에 대해서는 크게 다루지 않겠습니다.


언어별 장단점 간단 정리

C++

  • 당연하게도 수행 시간과 메모리 효율이 가장 좋습니다. 앞서 말씀드린대로 더 이상 설명은 생략하겠습니다.
  • C++ 언어는 오래 전부터 대회 등에서 가장 많이 사용된 언어이기 때문에 엄청난 양질의 참고자료가 압도적으로 많습니다. 요즘은 Python 자료가 많이 생겨나고 있긴 하지만 특히 고급 개념들을 사용한 알고리즘의 경우에는 C++의 자료를 따라 갈 수 없습니다. 재야의 고수(?)들이 주로 사용하는 언어이기 때문이라고 합니다...
  • 표준 템플릿 라이브러리(STL)가 매우 잘 되어있습니다. C언어에서는 직접 구현해야하는 자료구조나 정렬, 이진탐색 등의 알고리즘이 C++에서는 STL에서 기본적으로 제공되며 그 라이브러리들이 특히, 알고리즘 문제 해결에 강력한 효율성과 시간 단축을 제공하기 때문에 엄청난 장점이라고 할 수 있습니다.
  • 하지만 역시 Low Level에 가까운 언어라는 점에서 메모리, 세그먼트, 자료형 등에 대한 지식을 어느정도 갖고 있어야합니다. 배열의 크기를 너무 크게 선언하거나 전역 변수가 아닌 지역 변수로 선언할 경우 스택 메모리의 할당 되어 범위가 제한되거나, 자료형 별로 범위가 있기 때문에 신경써서 선언해줘야 한다는 점 등이 존재합니다. 이처럼 로직 외에 신경써야하고 알아야할 부분이 많다는 점이 단점이라고 할 수 있습니다.
  • 또한 매개변수로 객체나 구조체를 넘겨줘야하는 경우 포인터를 사용해줘야 합니다. 물론 포인터 사용에 익숙하고 오히려 포인터의 사용이 더 편리한 사람들도 있으나 저 같은 코린이(?)에게는 많이 헷갈릴 수 있는 부분입니다. 이때는 보통 전역변수로 선언하여 접근하는 방식으로 구현합니다.

Java

  • 실무, 특히 국내 백엔드 프레임워크로서 가장 많이 사용되는 언어입니다. 따라서 Java를 사용한 알고리즘 풀이가 익숙해진다면 Java를 활용한 프로그램 개발에 많은 도움이 될 수 있습니다.
  • 보통 Java의 수행 시간의 경우 같은 로직일 때의 C/C++ 과 Python의 중간 속도이지만 가끔은(?) Python 보다도 느린 수행 시간이 나오기도 합니다.
  • 완전한 객체지향 언어이기 때문에 입출력만 하는데에도 객체 생성과 초기화 때문에 꽤 여러 줄의 코드를 작성해야합니다.  
  • 단, IntelliJ와 같은 파워풀한 IDE를 사용하여 자동 완성 및 Snippet 기능을 활용하면 코드 작성에 많은 시간 단축을 할 수 있습니다. 다만 자체 웹 IDE를 사용하는 코딩 테스트의 경우에는 이러한 기능을 쓸 수가 없고 심지어 라이브러리도 직접 import 코드를 작성해주어야 합니다.
  • Java는 기본적으로 포인터라는 개념이 존재하지 않습니다. 따라서 기본 자료형의 경우에는 Call by Value를 통한 값복사가 이뤄지지만 Class와 같은 참조 자료형에게는 Call by Reference를 통한 얕은 복사가 이뤄집니다. 따라서 매개변수로 참조 자료형 변수를 넘겨준다면 포인터에 대해 신경써야할 필요가 전혀 없습니다.
  • 하지만 역시 알고리즘 구현보다는 개발에 더 적합한 언어라고 할 수 있습니다. C++만큼 코딩테스트에 유리한 표준 라이브러리가 부족하고 문법이 생각보다 까다롭고 어렵습니다. 무엇보다 객체지향이라는 개념을 확실히 이해하고 숙지해야 코드 작성이 수월해집니다.

Python

  • 우선 앞의 언어들 보다 같은 로직일 경우 평균 수행 시간이 많이 느린 편입니다.
  • 하지만 기본적으로 제공되는 list가 C++의 vector 기능을 수행할 뿐만 아니라 인덱싱, 슬라이싱, 삭제, 삽입 등의 기능을 자유롭게 사용할 수 있다는 점 덕분에 이 언어가 가지는 압도적인 장점이라고 할 수 있습니다. 심지어 같은 리스트에 다양한 자료형을 저장할 수 있습니다...
     
  • 문자열 또한 리스트처럼 접근 가능하며 replace와 같이 다양한 함수 모듈을 제공하기 때문에 문자열 처리가 매우 쉽고 간편합니다.
  • 또한 매우 다양하고 파워풀한 모듈 및 기본 라이브러리가 제공되기 때문에 알고리즘 작성에도 많은 코드 단축과 효율성을 제공해주며, 그리고 보통 이러한 모듈들의 사용과 유연한 구현 방식으로 정말 짧고 가독성 있게 작성되는 코드들을 Pythonic 하다고 말합니다.
  • Python의 정수 자료형은 Arbitrary-precision arithmetic을 사용하기 때문에 범위가 무제한입니다. 따라서 오버플로우를 신경 쓸 필요가 전혀 없다는 것도 정말 큰 장점입니다.
  • Print 함수를 통해 리스트 요소를 반복문을 통해 일일이 출력하지 않아도 한꺼번에 출력할 수 있으며 다양한 자료형의 형태도 출력을 통해 확인이 가능하다는 점 덕분에 디버깅이 매우 간편합니다.
  • 위에서 설명한 간편함과 강력함이 Python의 코드를 짧게 만들어주고 별다른 하드웨어적 지식은 필요없이 핵심 로직만 구현하면 된다는 것도 이 언어의 메리트라고 할 수 있습니다. 하지만 들여쓰기로 블록을 구분한다는 점이 오히려 가독성을 해치거나 오류를 발생시킬 수도 있다는 점이 가끔은 불편한 요소라고 할 수 있겠습니다. 

 

그렇다면 언제 어느 언어를 사용하는게 좋을까?

만약 세 언어 중의 하나의 언어가 특출나게 능숙하다면 그 언어를 사용하는 것이 맞습니다. 하지만 만약 두 개 이상의 언어가 역량이 비슷하다면 어떤 상황에 어떤 언어를 사용하는 것이 좋을까요?

저는 보통 '아 이 문제는 파이썬으로 하면 금방 풀릴 거 같다' 하는 경우에 Python 언어로 해결하고 그 외에 복잡한 로직 구현이나 코드 작성이 길어지는 경우에는 C++로 해결하는 편입니다. 그래도 어느 상황에서 어느 언어를 사용하면 좋을지에 대한 선택 요소가 있으면 좋을것 같아 정리해 보았습니다.

C++

  • 포인터를 사용할 수 있기 때문에 연결 리스트와 같이 다른 노드를 가르키는 자료 구조를 구현하기에 매우 용이합니다. 따라서 자료구조를 구현하는 문제의 경우 매우 적합한 언어입니다.
  • Python이 블록을 들여쓰기로 구분한다는 점이 저에게는 코드가 길어지거나 함수가 많아질 때 가독성이 많이 불편해집니다. 따라서 로직 구현이 많아지거나 함수가 많아질 경우에 C++로 사용합니다.

Java

  • 특정 노드에 대한 정보가 많은 경우 경우 이를 Class의 필드와 메소드를 통해 구현하면 가독성이 매우 높아집니다. 또한 Java의 경우 참조 자료형의 매개 변수는 얕은 복사로 접근하기 때문에 포인터에 대한 신경을 쓸 필요가 없으며 객체를 자주 활용하고 다루는 문제에서는 정말 강력한 언어라고 할 수 있습니다.  

Python

  • 문자열, 해싱과 같은 문제에서 다른 언어들에 비해 매우 편리하고 짧게 코드를 작성할 수 있습니다. 특히 그 중에 'in' 이라는 키워드는 Pythonic을 대표하는 키워드라고 생각하며 리스트, 문자열, 딕셔너리 등 여러 자료구조를 탐색할 때 매우 편리하게 사용할 수 있습니다.
  • Python 모듈이나 라이브러리로 한번에 처리가 가능한 문제의 경우 사용합니다. 특히 itertools.combinations나 itertools.product, collections.Counter 와 같은 메소드들이 이러한 대표적인 강력한 라이브러리라고 할 수 있습니다.

아직 부족한 역량 때문에 어느 문제에서 특정 언어를 사용해야 되는지에 대한 선택지를 많이 작성하지 못한 것 같습니다. 앞으로 더 많은 문제 해결을 해보면서 어느 상황에 어느 언어로 해결하면 좋을지에 대한 고민을 계속해서 해보면서 본 포스팅을 업데이트 하도록 하겠습니다. 또한 댓글로 피드백과 의견을 주시면 적극 반영하도록 하겠습니다.


언어별 알고리즘 문제 해결 포스팅

앞으로 알고리즘 문제 해결에 대한 포스팅을 세 가지 언어별로 차례대로 업로드할 예정입니다. 포스팅 내용에는 입출력 속도 향상 코드라던지, 문자열을 다루는 방법, 구조체는 클래스 선언 방식, 그 언어의 주의사항 및 팁 등을 다룰 예정입니다. 또한 알고리즘 해결에 유용한 표준 라이브러리의 정리와 사용 방법에 대해서도 다룰려고 합니다. 업로드하는 대로 본 포스팅에 링크를 업데이트 하도록 하겠습니다.


결론

사실 문제마다 특정 언어를 선택해서 해결하기 보다 한 언어라도 정말 능숙하게 다룰 수 있는 것이 더 중요하다고 생각합니다. 그래도 각자 언어의 장단점이 확실히 존재하기 때문에 본 포스팅을 작성해보았고 언어 선택의 기로에 놓이신 분들에게도 도움이 되셨으면 합니다. 이상 본 글 작성을 위해 자료 조사를 하면서 알게된 기막힌 그래프 툴 사이트를 첨부하며 본 포스팅을 마치도록 하겠습니다.
https://csacademy.com/app/graph_editor/ 

 

CS Academy

 

csacademy.com

 

반응형