ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [프로그래머스 1단계] 알고리즘 2. 최대값과 최소값
    24년 11월 이전/레거시-알고리즘(3) 2018. 2. 12. 23:41
    반응형

    문제 출처는 프로그래머스 알고리즘 연습 에서 볼 수 있습니다!(https://programmers.co.kr/learn/challenges)



    알고리즘 2. 최대값과 최소값 구하기. 입력값은 "숫자(공백)숫자(공백)... 숫자" 이런 형식의 문자열이다. 이 문자열에서 최대값과 최소값을 찾아 "최소값(공백)최대값" 형식의 문자열을 반환하는 함수를 만드시오.


    public class GetMinMaxString {

        public String getMinMaxString(String str) {

            return "";

        }


        public static void main(String[] args) {

            String str = "1 2 3 4";

            GetMinMaxString minMax = new GetMinMaxString();

            //아래는 테스트로 출력해 보기 위한 코드입니다.

            System.out.println("최대값과 최소값은?" + minMax.getMinMaxString(str));

        }

    }


    풀이 : 이번에는 자바8 스트림 API를 이용하여 함수형 프로그래밍으로 문제를 풀어볼 것이다. 먼저 어떻게 풀어야할지 생각해보자. 나의 방식은 이러했다.


    1. 주어진 입력 문자열을 통해서 숫자로 된 문자열들을 추출한다.

    2. 숫자로 된 문자열들을 숫자로 바꾼다.

    3. 바뀐 숫자들을 정렬하여 최대값 최소값을 구한다.


    그렇다면 이제 실제로 입력값인 문자열 str에서 숫자를 추출해보자. 이 작업은 자바의 String 클래스의 split 메소드를 이용하면 쉽게 풀 수 있다. 문자열 형식을 다시 한 번 보자.


    "숫자(공백)숫자(공백)....숫자" -> "-1 5 3 2 0 1 4" 


    이런식으로 문자열의 형식이 정해져있다. 여기서 잠깐 split 메소드를 살펴보자. API에 따르면


    String[] split(String regex);


    로 되어 있다. 그렇다. split 메소드는 정규표현식에 따라 문자열을 쪼개서 문자열 배열을 만들어주는 함수이다. 우리가 제거해야할 문자들은 공백 문자이다. 따라서 


    str.split(" "); -> ["-1", "5", "3", "2", "0", "1", "4"] 


    를 호출하면 숫자로 이루어진 문자열 배열을 얻을 수 있다. 자 첫번째 단계가 끝났다. 이제 문자열들을 숫자로 바꿔야한다. 이는 Stream API의 map 메소드로 쉽게 풀이가 가능하다. 물론 그 전에 split을 통해 얻은 문자열 배열을 컬렉션으로 바꿔야 한다. 왜냐하면 기본적으로 스트림API는 컬렉션에만 제공이 되기 때문이다.(물론 자바는 기본형에 대한 스트림도 지원합니다. 예를 들어 IntStream 같은 것들이 그 지원 중 하나죠)

    문자열 배열을 컬렉션으로 바꾸기 위해서 Arrays.asList() 함수를 이용할 것이다.


    list = Arrays.asList(str.split(" ")); -> String[] => List<String>


    스트림 사용법은 그 컬렉션에 stream()를 이용하면 된다. 자 이제 스트림을 사용할 준비가 다 되었다. 이제 두 번째 단계 추출한 숫자인 문자열들을 정수형 숫자로 바꿔보자.


    list = list.stream()                                List<String> -> Stream<String>

                    .map( s -> Integer.parseInt(s))    Stream<String> -> Stream<Integer>
                    .collect(Collectors.toList());         Stream<Integer> -> List<Integer>


    이는 컬렉션 요소의 타입을 String에서 Integer 타입으로 변환시킨다. 여기서 


    s -> Integer.parseInt(s)


    부분은 람다식인데 간단히 입력값 String s를 Integer.parseInt(s)를 통하여 정수값을 출력시키는 부분이다. map은 이렇게 개발자가 각 요소를 원하는 타입으로 모조리 바꿔버릴때 유용하다. 이제 마지막 단계인 정렬을 해보자. Collectors.sort 메소드를 이용할 것이다.


    Collectors.sort(list, (i1, i2) -> i1.compareTo(i2));


    sort는 첫번째로 컬렉션을 두번째로 그 비교해서 정렬시킬 수 있는 람다를 넣어주면 된다. 이러면 내림차순으로 정렬된다. 그러니 이제 "최소값(공백)최대값" 형식의 결과를 출력시키면 된다.


    int min = list.get(0);

    int max = list.get(list.size()-1);

    return min + " " + max;


    다음은 나의 코드 본문이다.


    import java.util.*;

    import java.util.stream.Collectors;


    public class GetMinMaxString {

        public String getMinMaxString(String str) {

          List<Integer> list = Arrays.asList(str.split(" "))

                                     .stream()

                                     .map(s -> Integer.parseInt(s))

                                     .collect(Collectors.toList());

          

          

    Collections.sort(list, Integer::compare);

    int min = list.get(0);

    int max = list.get(list.size()-1);

          

    /* stream api를 이용하여 끝까지 구한 코드

          int max = list.stream()

                        .max(Integer::compare)

                        .get();


          int min = list.stream()

                        .min(Integer::compare)

                        .get();

    */

          return min + " " + max;

        }


        public static void main(String[] args) {

            String str = "1 2 3 4";

            GetMinMaxString minMax = new GetMinMaxString();

            //아래는 테스트로 출력해 보기 위한 코드입니다.

            System.out.println("최대값과 최소값은?" + minMax.getMinMaxString(str));

        }

    }


    후 stream api를 이용하여 표현하는게 쉽지가 않구나...

    728x90
Designed by Tistory.