Codewars 문제풀기 (03/23)

Duplicate Encoder

  • String을 인자로 받는다.
  • 겹치는 문자가 있으면 ‘)’로 변환, 겹치지 않는 문자가 있으면 ‘(‘로 변환하여 리턴한다.
  • 대소문자는 구분하지않는다.

  • “din” –> “(((“
  • “recede” –> “()()()”
  • “Success” –> “)())())”
  • ”(( @” –> “))((“

1. Test를 만들었다.

  • 모든 문자가 겹치지 않을 때 ‘(‘로 변환해야한다.

    • 테스트 코드

        public void testShouldReturnOpenWhenAllCharactersAreNotDuplicate() {
          //Given : Set string all characters not duplicate
          String given = "abcdefghi";
          //When : Call encode
          String actual = DuplicateEncoder.encode(given);
          //Then : Should return "((((((((("
          assertEquals("(((((((((", actual);
        }
      
    • 실제 코드

      public class DuplicateEncoder {
          
        public static String encode(String word) {
          char[] toArray = word.toCharArray();
          for (int i = 0; i < toArray.length; i++) {
            char target = toArray[i];
            for (int j = i + 1; j < toArray.length; j++) {
              if (target == toArray[j]) {
                toArray[j] = ')';
                toArray[i] = ')';
              }
            }
            if (toArray[i] != ')') {
              toArray[i] = '(';
            }
          }
          return new String(toArray);
        }
      }
      
  • 모든 문자가 겹칠 때 ‘)’로 변환해야한다.

    • 테스트 코드

        @Test
        public void testShouldReturnCloseWhenAllCharactersAreDuplicate() {
          //Given : Set string all characters not duplicate
          String given = "abccbabca";
          //When : Call encode
          String actual = DuplicateEncoder.encode(given);
          //Then : Should return "((((((((("
          assertEquals(")))))))))", actual);
        }
      
    • 실제코드 그대로

  • 대소문자는 구별하지 않는다.

    • 테스트 코드

        @Test
        public void testShouldBeCaseInsensitive() {
          //Given : Set string all characters not duplicate
          String given = "Prespecialized";
          //When
          String actual = DuplicateEncoder.encode(given);
          //Then
          assertEquals(")()())()(()()(", actual);
        }
      
    • 실제 코드

      public class DuplicateEncoder {
          
        public static String encode(String word) {
          word = word.toLowerCase();
          char[] toArray = word.toCharArray();
          for (int i = 0; i < toArray.length; i++) {
            char target = toArray[i];
            for (int j = i + 1; j < toArray.length; j++) {
              if (target == toArray[j]) {
                toArray[j] = ')';
                toArray[i] = ')';
              }
            }
            if (toArray[i] != ')') {
              toArray[i] = '(';
            }
          }
          return new String(toArray);
        }
      }
      
      • word = word.toLowerCase()추가
      • 여기까지 생각하고 제출했는데 Fail이 떴다. “—-()(—“테스트를 통과하지 못했다.
  • ’)’, ‘(‘문자가 들어간 경우

    • 테스트 코드

        @Test
        public void testWhenContainOpenAndCloseMark() {
          //Given : Set string all characters not duplicate
          String given = "---()(---";
          //When
          String actual = DuplicateEncoder.encode(given);
          //Then
          assertEquals("))))())))", actual);
        }
      
    • 실제 코드

      public class DuplicateEncoder {
        static String encode(String word){
          word = word.toLowerCase();
          
          char[] encodingChar = new char[word.length()];
          char[] toArray = word.toCharArray();
          for (int i = 0; i < toArray.length; i++) {
            if (encodingChar[i] != '\0') {
              continue;
            }
            char target = toArray[i];
            for (int j = i + 1; j < toArray.length; j++) {
              if (target == toArray[j]) {
                encodingChar[j] = ')';
                encodingChar[i] = ')';
              }
            }
            if (encodingChar[i] != ')') {
              encodingChar[i] = '(';
            }
          }
          return new String(encodingChar);
        }
      }
      
      • 여기서 처음에 문자열을 ‘변환’한다는 생각에 덮어쓰려고 했었다.
      • 그래서 계속 fail이 떴는데 리턴할 배열을 따로 선언해서 구현하니 통과했다.
      • 이 과정에서 시간을 많이 썼다 ㅜㅜ
  • 리팩토링 고민하다가 문제 푸는것도 오래걸렸고, 생각도 안나서 그냥 제출했다.

2. 답 비교, 느낀점

Best Practice 가장 많이 받은 코드

public class DuplicateEncoder {
  static String encode(String word){
    word = word.toLowerCase();
    String result = "";
    for (int i = 0; i < word.length(); ++i) {
      char c = word.charAt(i);
      result += word.lastIndexOf(c) == word.indexOf(c) ? "(" : ")";
    }
    return result;
  }
}
  • lastIndexOf()메서드는 문자열에서 해당 문자의 가장 마지막 index를 반환한다. “abcabcabc”에서 lastIndexOf(‘a’)는 6이고, indexOf(‘a’)는 0이다.
  • 문자열에서 문자가 하나라면 lastIndexOf() == indexOf()이다. 그래서 반환할 문자열에 “(“를 붙여주면된다. 같지 않다면 “)”를 붙여준다.
  • 일단 문제를 푸는데도 오래걸려서 더 간단하게 푸는 방법을 아에 생각하지못했다. 그리고 문제를 “변환”한다는 생각에 replace메소드만 생각하거나, 인자 문자열에 덮어쓰는것만 생각했다. 문제를 좀더 유연하게 바라볼 필요가 있는것 같다 ㅜㅜ

댓글남기기