아나그램을 손코딩하시오

sample code )

anagramCheck("abcd","bcad");
anagramCheck("abcd","ecad");


public static boolean anagramCheck(String first, String second) {
    boolean result = false;
    return result;
}

위의 문제에 대해서 손코딩을 해보았습니다. 인터넷 검색 없이 하다보니, Arrays.sort 같은 메소드는 생각이 나기 쉽지않기에, 결국 기본문법만으로 코딩하게 됩니다.

  public static boolean anagramCheck(String first, String second) {
        int firstLength = first.length();
        int secondLength = second.length();

        if (firstLength != secondLength) {
            return false;
        }

        char[] firstChar = new char[firstLength];
        char[] secondChar = new char[secondLength];

        for (int i=0;i<firstLength;i++) {
            firstChar[i] = first.substring(i, i + 1).charAt(0);
        }

        for (int i=0;i<secondLength;i++) {
            secondChar[i] = second.substring(i, i + 1).charAt(0);
        }

        int check = 0;
        for (char firstA: firstChar) {
            for (char secondB: secondChar) {
                if (firstA == secondB) {
                    check++;
                }
            }
        }

        return check == firstLength;
    }

위와 같이 보드에 작성했는데, 손코딩이면 엄청 긴 문장이 되겠지요. 실제 손코딩에서는 charAt(0) 를 빠트린거랑, for문안에 안전장치로 if문을 하나 더 쓴거 빼고는 실제 손코딩했던 것과 동일한 로직을 구성했지만, 면접에서는 조금더 간결한게 좋을 거 같습니다.

실제 담당자가 원했던 결과는 Stream 을 사용한 간결한 코드로 작성일 수도 있습니다. 담당자에 따라 다르겠지요. 우선 손코딩 당시에는 기억이 나지 않았떤, toCharArray 메소드를 사용하여, char 로 변환해서 처리했습니다.

  public static boolean anagramCheck(String first, String second) {
      char[] fisrtChar = first.toCharArray();
      char[] secondChar = second.toCharArray();
      Arrays.sort(fisrtChar);
      Arrays.sort(secondChar);
      return new String(fisrtChar).equals(new String(secondChar));
  }

무려 5줄이면 끝나죠.

실제로 손코딩 당시에는 sort 는 전혀 생각나지 않았고, toCharArray 는 생각은 났으나, 실업무에는 안쓰는 메소드기에 철자가 틀리기 싷어 빼다보니 순수코딩의 라인이 길어지는 건 어쩔수가 없게 됩니다. 실제 넉넉한 마음으로 짜보니, 30 라인의 길이가 10라인까지 줄어들었습니다.

최종적으로 위의 줄인 로직을 기반으로 변경한 Stream API 처리로직은 다음과 같습니다.

public static boolean anagramCheck(String... list) {
    long count = Stream.of(list)
            .map(String::toCharArray)
            .peek(Arrays::sort)
            .map(String::valueOf)
            .distinct()
            .count();
    return count == 1;
}

넘어온 list 를 Stream에 담습니다. map 에 toCharArray를 담은 후 peek 로 ArrayList를 sort합니다. 다시 map으로 sort 된 값을 다시금 string으로 변환합니다. distinct로 중복된 값을 제외한 후 count()를 샙니다. 만약 char로 정렬되지 않을 경우, count는 1이 아니게 됩니다.

계속 공부를 해야합니다.