Algorithm/알고리즘 이론

Java vs Python3 vs C++ for coding test

Razelo 2021. 7. 30. 11:04

아래 두 코드는 같은 문제를 자바와 파이썬으로 각각 풀어낸 것이다. (오랜만에 풀어봤다.) 이분탐색문제였는데, 이 문제 뿐만 아니라 다른 문제들도 마찬가지로 작성해야할 코드의 양에 있어서 상당한 차이를 보였다.

 

자신이 가장 편한 언어를 선택하라고 해서 사실 c++과 파이썬, java중 어느 것을 선택하더라도 별 반 차이가 없는 상태에서 시작했었다. 당시에는 숙련도가 모두 비슷했었다. (c++ stl의 사용법을 100프로 알고있던 상태는 아니어서 c++의 경우 숙련도가 조금은 떨어지긴 했다.)

 

주로 사용하는 언어가 자바여서 자바로 주로 풀이하였는데, 한 문제를 풀면서 python으로도 똑같이 풀어보는 방식으로 진행했다. 한문제를 여러언어로 바꿔서 풀어본적이 대부분이었는데,  여지껏 문제를 풀면서 느낀 점이 있다. 

 

1. 파이썬: 다들 하는 말이지만, 정말 짧다. 특정 문제의 경우 두줄 내지 세줄로 끝나는 경우도 있고, 대부분의 경우 최대 두배 가까이 짧게 작성할 수 있다. 느리다는 말이 있지만, 특정 유형에서 속도가 조금 떨어지는 것은 사실이다. 이로 인해 제출이 오답으로 판정나는 경우가 있었는데, 코드를 최적화시켜주거나 혹은 pypy3로 제출할 경우 해결되었다. 아주 고난이도의 문제가 출시되는 곳, 혹은 대회에서 나올 법한 문제의 경우 실제로 이게 큰 단점으로 작용할 수 있겠지만, 이미 대회를 준비한다는 마음을 갖고 있으면 진작 c++을 선택했을테니 보통 코딩테스트를 준비하는 대다수 분들의 경우와는 맞지 않는 이야기라고 생각한다. 정말 간결하고, 말 그대로 로직에만 집중할 수 있는 게 마음에 들었다. 어느 분들은 로직만 알면 이미 문제를 해결한 것이니 사실 언어가 별 상관없는게 맞다라고 하시는데, 맞는 말이라는 것을 인정한다. 하지만 눈에 확 들어오는 간결한 코드 속에서 로직에 집중할 수 있는 것이 파이썬의 매력인 것도 맞는 말이라고 생각한다.

 

2. 자바: 어느 커뮤니티에서 제발 자바쓰지말고 c++이나 파이썬 쓰라고 강력히 어필하면서 좋은 점이 BigInteger말고는 없다고 열변을 하시던데, 그 당시에는 언어가 무슨 상관이냐. 내가 편하게 쓰는 걸로 하면 된거지. 라는 생각을 했었다. 하지만 쓰다보니 불편한점이 여간 한둘이 아니었다. 실제로 아주 간단한 동작마저도 추가적인 코드를 작성하는 경우가 있었고, 파이썬에 비해서 확실히 신경써줘야할 부분이 몇 군데 더 있다. (이건 파이썬 vs c++의 경우에서 c++도 마찬가지인 것 같다.) 코드가 굉장히 장황해진다. (사실 이전까지는 자바의 장황함에 대해서 들어보기만 했고, 크게 체감하지는 못했었다. 하지만 정해진 시간 속에서 코드를 빠르게 작성해야하는 상황에 닥치니 실제로 체감이 많이 되었다. 가뜩이나 바쁜데 부가적인 기능에 불과한 코드를 작성하는데 시간이 소요되는 게 마음에 들지 않았다. ) 따라서... 단점이 꽤 부각되는 선택이라고 생각한다. 정말로 익숙하고, 오히려 자바를 사용하는 걸 취향적으로 좋아한다면? 굳이 선택해도 할 말은 아니지만, 굳이 내가 쓰고 싶진 않다.

 

3. c++: 빠르다는 이야기는 정말 맞다. 실제로 빠르다. 위에 언급된 두 언어를 포함해서 세 언어로 같은 문제를 풀면 모든 경우에서 그냥 빠른게 아니라 압도적으로 빨랐다. 하지만 이외의 장점에 대해서는 자바와 비교했을때는 별반 차이를 느끼지 못했다. 가끔 포인터가 유용하게 사용될 때가 있지만, 정말 가끔이고, 사실 대부분의 경우 값을 전달하는 과정, 파라미터를 넘기는 과정에서 이를 통해 엄청한 이득을 얻기는 특수한 경우가 아닌 이상 해당되지 않을 것 같다. stl의 경우 정말 강력한 라이브러리인 것은 확실한 것 같다. 자바 컬렉션과 비교했을때, 나은 점이 몇 군데 있었다. 조금 더 구체적인 메서드를 제공하여 다양하게 활용할 수 있게 제공하는 점이 매력적이었다. 하지만 이역시도 파이썬과 비교했을 때는 코드의 분량에 있어서 압도적인 차이가 발생하는 것이 사실이었다. 대회를 준비한다면 c++을 사용하는 게 나을 것 같다는 생각이 들었고, 그외의 경우에는 자바보다는 c++을 선택하는 것이 낫겠다는 생각이 들었다.

 


결론:

대회 -> c++

본인의 실력 향상(혹은 문제 푸는게 정말 재밌거나...) -> 자신이 원하는 언어 선택 (하고싶은 언어 아무거나 가능)

취업이라면 -> 파이썬 > c++ > 자바

 

 

파이썬:

T = int(input())
while T: 
    T -= 1
    N = int(input())
    arr1 = list(map(int, input().split(" ")))

    M = int(input())
    arr2 = list(map(int, input().split(" ")))

    arr1.sort() #arr1 정렬해주기 
    for i in arr2:
            first = 0
            last = len(arr1) - 1
            mid = 0 
            flag = False
            while first <= last:
                mid = (first + last) // 2
                if arr1[mid] == i:
                    print(1)
                    flag = True
                    break
                else:
                    if i < arr1[mid]:
                        last = mid - 1
                    else:
                        first = mid +1 

            if not flag:
                print(0)

자바:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Scanner;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws Exception{
        //1016
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        StringBuilder sb = new StringBuilder();
        int T = Integer.parseInt(br.readLine());
        while(T != 0){
            T--;
            int N = Integer.parseInt(br.readLine());
            st = new StringTokenizer(br.readLine(), " ");
            int[] arr1 = new int[st.countTokens()];
            int i = 0;
            while(st.hasMoreTokens())
                arr1[i++] = Integer.parseInt(st.nextToken());

            int M = Integer.parseInt(br.readLine());
            st = new StringTokenizer(br.readLine(), " ");
            int[] arr2 = new int[st.countTokens()];
            i = 0;
            while(st.hasMoreTokens())
                arr2[i++] = Integer.parseInt(st.nextToken());

            Arrays.sort(arr1);

            for(int k = 0; k<arr2.length; k++){
                int result = binarySearch(arr1, arr2[k]);
                sb.append(result + "\n");
            }
        }
        System.out.println(sb);
    }
    private static int binarySearch(int[] arr, int n){
        int first = 0;
        int last = arr.length - 1;
        int mid = 0;
        while(first <= last){
            mid = (first + last) / 2;
            if(arr[mid] == n){
                return 1;
            }
            else{
                if(n < arr[mid])
                    last = mid - 1;
                else
                    first = mid + 1;
            }
        }
        return 0;
    }
}

 

반응형