본문 바로가기

개발/DS&Algorithms

[TIL] Daily Coding 회고 - 문자열

안녕하세요😎 백엔드 개발자 제임스입니다 :)

오늘은 코드스테이츠에서 제공하는 문제에 대해 회고하려고 합니다. 이수하고 있는 교육에서 매일 한 개씩 코딩 문제를 풀고 있습니다. 날이 지날수록 난이도가 점점 올라가 어려워지고 있는데요. 그중 오늘 푼 문제는 저의 아이디어로 풀기는 했으나, 레퍼런스의 풀이 방식을 오래 기억하고 싶어 이렇게 기록합니다.

* 문제의 자세한 내용은 공유하지 않습니다.

내가 푼 풀이

public static String readVertically(String[] arr) {
    // TODO:
    String result = "";
    int newStrLength = 0;

    for(int i = 0; i < arr.length; i++) {
        newStrLength += arr[i].length();
    }

    int column = 0; // 열
    int row = 0; // 행

    while(newStrLength-- > 0) {
        if(column == arr.length) {
            column = 0;
            row++;
        }
        while(row >= arr[column].length()) {

            column++;
        }
        result += String.valueOf(arr[column].charAt(row));

        column++;
    }

    return result;
}

저의 풀이는 이렇습니다. 인자로 받은 String 배열의 문자열과 각 문자열의 글자들을 행(row), 열(column)로 배치하여 생각했습니다. 

가장 먼저 배열 안에 각 문자열의 길이를 더한 만큼 프로세스를 반복하게 했습니다. 반복을 진행하면서 행과 열에 해당하는 문자를 빈 문자열인 result 에 더해주는 방식으로 진행했습니다. 예를 들어 처음은 행 0번과 열 0번에 해당하는 값이 추가되게 됩니다. 그리고 세로 방향으로 위치한 문자를 더해주어야 하기 때문에, 열(column)의 인덱스에서 +1 을 진행합니다. 이렇게 진행하면, 각 문자를 세로로 읽으며, 새로운 문자열을 생성하게 됩니다.

여기서 저는 두 가지의 반례를 생각했습니다. 첫 번째는 세로로 읽는데 마지막 열까지 읽었다면, 첫 번째 문자열의 다음 문자를 읽어야 합니다. 따라서 저는 +가 적용된 column 이 초기 배열의 길이와 동일할 때 column을 0으로 선언하고, 행을 1 증가시켰습니다. 즉, 읽고 있는 지점을 옆으로 옮긴 것이죠.

두 번째는 행을 옆으로 옮겼으나 더 이상 문자가 없을 때입니다. 만약 무시하고 진행하다면, NullPointException 또는 IndexOutBounds 에러가 발생하게 됩니다. 저는 이러한 경우 에러가 발생하지 않게, column에 +1을 진행하여 다음 열의 문자를 추가하도록 코드를 작성했습니다.

이렇게 푼 결과는 아래와 같이 나오게 되었습니다.

결과

보다시피 두 개의 에러가 발생했습니다. 우선 아래 3개 결과를 보면, 의도한대로 출력하는 것을 볼 수 있습니다. 바로 위 두 개 에러가 발생한 원인을 추측해보자면, 아마 마지막 문자까지 세로로 읽은 뒤 다음 열로 넘어가려는 프로세스 때문에 위와 같은 문제가 발생한 것 같습니다. 다시 말하면, 이 과정이 가로로 읽는 행위가 되어 버린 것이죠.

 

레퍼런스

public class Solution { 
	public String readVertically(String[] arr) {
    
    int maxLength = 0;

    for(int i = 0; i < arr.length; i++) {
      if(maxLength < arr[i].length()) {
        maxLength = arr[i].length();
      }
    }
    
    String[] temp = new String[maxLength];
    
    for(int i = 0; i < arr.length; i++) {
      String str = arr[i];
    
      for(int j = 0; j < str.length(); j++) {
    
        if(temp[j] == null) {
    
          temp[j] = Character.toString(str.charAt(j));
    
        } else {
          temp[j] = temp[j] + str.charAt(j);
        }
      }
    }
    
    String result = "";
    for(int i = 0; i < temp.length; i++) {
      result = result + temp[i];
    }

    return result;
  }
}

저는 레퍼런스를 보고 큰 충격을 받았습니다. 그래서인지 이 풀이 방식을 기억하고 싶었습니다.

풀이를 보자면, 먼저 배열 내의 문자열 중 가장 큰 길이를 찾고, 해당 길이 만큼의 배열을 새롭게 만들었습니다. 이제 초기 입력받은 배열만큼 순회를 진행합니다. 인덱스 별로 문자들이 있는데요. 이중 for문을 통해서 각 문자열의 문자가 위치한 인덱스로 새로 만든 배열에 추가가 됩니다.

만약 첫번째 인덱스의 문자열이 길이가 4라면, 새로운 배열의 인덱스 3까지 순차적으로 저장이 됩니다. 이렇게 모든 문자열을 똑같이 진행합니다. 이제 새롭게 만든 배열에는 각 인덱스마다 새로운 문자들이 연결된 채 저장되어 있습니다. 그리고 모두 연결시켜서 출력하면, 원하는 결과가 나옵니다.

저는 이 풀이가 마치 그릇에 담는 행위처럼 느껴졌습니다. 다른 다양한 문제에서 활용할 수 있도록 잊지 말아야겠습니다.

반응형