May 23 2008
(IBM DW)코드 트레이닝 Part2. 알고리즘과 성능 - 트랙백
IBM developerWorks에서 재밌는 기사를 보아서 회사 일도 얼추 끝냈고 해서 잠깐 시간 내서 풀어봤다.
음… 문제는 상당히 쉽다. 학부 1~2학년 과제 수준인 것 같다.
물론 그냥 풀 때의 얘기이고, 다른 알고리즘 방법을 찾는다던지 하면 더 걸릴 수도 있을 듯…
다른 알고리즘 찾는 건 시간 날 때 해봐야지. 일단 일반적인 알고리즘으로 1~4를 해결했다.
솔직히 얘기하자면, 문제를 읽어보자 마자 일반적인 알고리즘이 생각났고 새로운 알고리즘 찾는 게 귀찮았다.
(그래서 일반적인 알고리즘으로 푼 것이다. ㅜ.ㅜ 그리고 다른 방법이 딱히 생각나지도 않는다. 다른 방법이 있긴 한건가…;;)
음… 이러면 안되는데…
내 풀이 ..
퀴즈 1. Both
public static ArrayList both(ArrayList xs, ArrayList ys) { ArrayList bothList = new ArrayList(); Object y = null; // 먼저 첫 번째 리스트를 몽땅 저장 bothList.addAll(xs); Iterator elems = ys.iterator(); while( elems.hasNext() ) { y = elems.next(); // 첫 번째 리스트에 값이 없을 경우에만 추가 if( !xs.contains(y) ) bothList.add(y); } return bothList; } |
: 코드를 보면 알겠지만 Either()랑 거의 똑같다 -_-;;
퀴즈 2. fastEither
public static ArrayList fastEither(ArrayList xList, ArrayList yList) { ArrayList eitherList = new ArrayList(); final int xSize = xList.size(); final int ySize = yList.size(); Comparable x, y; int order, xpos, ypos; xpos = ypos = 0; while( xpos < xSize && ypos < ySize ) { x = (Comparable)xList.get(xpos); y = (Comparable)yList.get(ypos); order = x.compareTo(y); if( order < 0 ) { // x가 작음 xpos++; } else if( order > 0 ) { // y가 작음 ypos++; } else { // x = y eitherList.add(x); xpos++; ypos++; } } return eitherList; } |
: 마찬가지로 코드를 보면 알겠지만 fastBoth()랑 거의 똑같다 -_-;;
퀴즈 3. isSubstring
public static boolean isSubstring(char[] left, char[] right) { final int leftCount = left.length; final int rightCount = right.length; for( int i = 0 ; i < rightCount ; i++ ) { if( left[0] == right[i] ) { boolean same = true; for( int j = 1 ; j < leftCount ; j++ ) { if( left[j] != right[i+j] ) { same = false; break; } } if( true == same ) return true; } } return false; } |
: 첫 글자 일치하면 2, 3, … , n 번째 글자까지 맞는지 확인
퀴즈 4. match
public class MatchTest { private static final String KIND_OF_BRACKETS_LEFT = "([< {"; private static final String KIND_OF_BRACKETS_RIGHT = ")]>}"; public static boolean isLeftBrackets(char ch) { if( -1 == KIND_OF_BRACKETS_LEFT.indexOf(ch) ) return false; return true; } public static boolean isRightBrackets(char ch) { if( -1 == KIND_OF_BRACKETS_RIGHT.indexOf(ch) ) return false; return true; } public static boolean isBracketMatch(char leftBracket, char rightBracket) { int leftBracketIdx = KIND_OF_BRACKETS_LEFT.indexOf(leftBracket); int rightBracketIdx = KIND_OF_BRACKETS_RIGHT.indexOf(rightBracket); if( (-1 == leftBracketIdx) || (-1 == rightBracketIdx) ) return false; return (leftBracketIdx == rightBracketIdx); } public static boolean matchUseStack(char[] cs) { final int length = cs.length; if( 0 == length ) return false; // 길이가 0인 경우도 짝이 없다고 가정함 /* * ArrayList로 할 수도 있지만 배열 사이즈가 어느 정도 정해져 있기 때문에 이렇게 함 * cs의 크기가 크다면 ArrayList가 나을 수도 있음(하지만 ArrayList를 사용하면 Object로 저장해야 함) * * Stack의 길이는 cs의 길이의 반이면 됨, 그 이상 넘어가면 짝이 있을 수 없음. */ int stackLen = length / 2; char[] stack = new char[stackLen]; int stackIdx = 0; for( int i = 0 ; i < length ; i++ ) { char ch = cs[i]; if( isLeftBrackets(ch) ) { // Stack에 집어넣음 if( stackIdx >= stackLen ) { // Stack이 꽉 찼음. 짝이 없음을 의미 return false; } stack[stackIdx] = ch; stackIdx++; } else if( isRightBrackets(ch) ) { // Stack에서 하나를 빼서 비교 if( stackIdx >= 0 ) { stackIdx--; char stackCh = stack[stackIdx]; // 꺼낸 괄호가 짝이 아니면 짝이 아님을 리턴 if( !isBracketMatch(stackCh,ch) ) return false; } else { // Stack에서 꺼낼 왼쪽 괄호가 없음. 짝이 없음을 의미 return false; } } // 괄호 종류가 아니면 무시 } return true; } public static boolean match(char[] cs) { return matchUseStack(cs); } public static void main(String[] args) { char[] first = { '(', '[', '< ', '{', '}', '>', ']', ')' }; char[] second = { '(', '[', '< ', '{', '>', '}', ']', ')' }; char[] third = { '(', 'a', 'c', ')', '[', '{', '}', ']' }; System.out.println( match(first) ); // yes System.out.println( match(second) ); // no System.out.println( match(third) ); // yes } } |
: Stack을 이용해서 left-bracket은 Stack에 쭉 넣고, right-bracket이 나오면 Stack에서 꺼내서 비교하는 알고리즘(이라고 하기도 민망;;)
