기술적 문제(2) 가능한 최선의 수행 시간

7일차 게일 라크만 맥도웰의 코딩 인터뷰 완전 분석 p.108 ~ p. 130 내용 정리 7. 기술적 문제 가능한 최선의 수행 시간(Best Conceivable Runtime(BCR)) BCR이 무엇일까 생각해 보는 것으로도 문제를 푸는데 유용한 힌트를 발견할 수 있다. 가능한 최선의 수행시간(Best Conceivable Runtime): 상상할 수 있는 모든 해법 중 가장 빠른 알고리즘의 수행 시간을 의미 최선의 경우의 수행 시간(Best Case Runtime): 특정 알고리즘이 가장 빠르게 동작할 경우의 수행 시간을 의미 따라서 둘은 아무 관계가 없다. ...

2023년 9월 11일 · 3 분 · 배준수

점진적인 개선(4)

책너두 5기 31일차 로버트 C. 마틴의 클린코드 p. 288~ p.295 내용정리 14. 점진적인 개선 1차 리팩터링한 결과물은 다음과 같다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 package com.objectmentor.utilities.args; import java.text.ParseException; import java.util.*; public class Args { private String schema; private String[] args; private boolean valid = true; private Set<Character> unexpectedArguments = new TreeSet<Character>(); private Map<Character, ArgumentMarshaler> marshalers = new HashMap<Character, ArgumentMarshaler>(); private Set<Character> argsFound = new HashSet<Character>(); private int currentArgument; private char errorArgumentId = '\0'; private String errorParameter = "TILT"; private ErrorCode errorCode = ErrorCode.OK; private enum ErrorCode { OK, MISSING_STRING, MISSING_INTEGER, INVALID_INTEGER, UNEXPECTED_ARGUMENT } public Args(String schema, String[] args) throws ParseException { this.schema = schema; this.args = args; valid = parse(); } private boolean parse() throws ParseException { if (schema.length() == 0 && args.length == 0) return true; parseSchema(); try { parseArguments(); } catch (ArgsException e) { } return valid; } private boolean parseSchema() throws ParseException { for (String element : schema.split(",")) { if (element.length() > 0) { String trimmedElement = element.trim(); parseSchemaElement(trimmedElement); } } return true; } private void parseSchemaElement(String element) throws ParseException { char elementId = element.charAt(0); String elementTail = element.substring(1); validateSchemaElementId(elementId); if (isBooleanSchemaElement(elementTail)) marshalers.put(elementId, new BooleanArgumentMarshaler()); else if (isStringSchemaElement(elementTail)) marshalers.put(elementId, new StringArgumentMarshaler()); else if (isIntegerSchemaElement(elementTail)) { marshalers.put(elementId, new IntegerArgumentMarshaler()); } else { throw new ParseException(String.format("Argument: %c has invalid format: %s.", elementId, elementTail), 0); } } private void validateSchemaElementId(char elementId) throws ParseException { if (!Character.isLetter(elementId)) { throw new ParseException("Bad character:" + elementId + "in Args format: " + schema, 0); } } private boolean isStringSchemaElement(String elementTail) { return elementTail.equals("*"); } private boolean isBooleanSchemaElement(String elementTail) { return elementTail.length() == 0; } private boolean isIntegerSchemaElement(String elementTail) { return elementTail.equals("#"); } private boolean parseArguments() throws ArgsException { for (currentArgument = 0; currentArgument < args.length; currentArgument++) { String arg = args[currentArgument]; parseArgument(arg); } return true; } private void parseArgument(String arg) throws ArgsException { if (arg.startsWith("-")) parseElements(arg); } private void parseElements(String arg) throws ArgsException { for (int i = 1; i < arg.length(); i++) parseElement(arg.charAt(i)); } private void parseElement(char argChar) throws ArgsException { if (setArgument(argChar)) argsFound.add(argChar); else { unexpectedArguments.add(argChar); errorCode = ErrorCode.UNEXPECTED_ARGUMENT; valid = false; } } private boolean setArgument(char argChar) throws ArgsException { ArgumentMarshaler m = marshalers.get(argChar); try { if (m instanceof BooleanArgumentMarshaler) setBooleanArg(m); else if (m instanceof StringArgumentMarshaler) setStringArg(m); else if (m instanceof IntegerArgumentMarshaler) setIntArg(m); else return false; } catch (ArgsException e) { valid = false; errorArgumentId = argChar; throw e; } return true; } private void setIntArg(ArgumentMarshaler m) throws ArgsException { currentArgument++; String parameter = null; try { parameter = args[currentArgument]; m.set(parameter); } catch (ArrayIndexOutOfBoundsException e) { errorCode = ErrorCode.MISSING_INTEGER; throw new ArgsException(); } catch (ArgsException e) { errorParameter = parameter; errorCode = ErrorCode.INVALID_INTEGER; throw e; } } private void setStringArg(ArgumentMarshaler m) throws ArgsException { currentArgument++; try { m.set(args[currentArgument]); } catch (ArrayIndexOutOfBoundsException e) { errorCode = ErrorCode.MISSING_STRING; throw new ArgsException(); } } private void setBooleanArg(ArgumentMarshaler m) { try { m.set(" true"); } catch (ArgsException e) { } } public int cardinality() { return argsFound.size(); } public String usage() { if (schema.length() > 0) return "-[" + schema + "]"; else return ""; } public String errorMessage() throws Exception { switch (errorCode) { case OK: throw new Exception("TILT: Should not get here."); case UNEXPECTED_ARGUMENT: return unexpectedArgumentMessage(); case MISSING_STRING: return String.format("Could not find string parameter for -%c.", errorArgumentId); case INVALID_INTEGER: return String.format("Argument -%c expects an integer but was '%s'.", errorArgumentId, errorParameter); case MISSING_INTEGER: return String.format("Could not find integer parameter for -%c.", errorArgumentId); } return ""; } private String unexpectedArgumentMessage() { StringBuffer message = new StringBuffer("Argument( s) -"); for (char c : unexpectedArguments) { message.append(c); } message.append("unexpected."); return message.toString(); } public boolean getBoolean(char arg) { Args.ArgumentMarshaler am = marshalers.get(arg); boolean b = false; try { b = am != null && (Boolean) am.get(); } catch (ClassCastException e) { b = false; } return b; } public String getString(char arg) { Args.ArgumentMarshaler am = marshalers.get(arg); try { return am == null ? "" : (String) am.get(); } catch (ClassCastException e) { return ""; } } public int getInt(char arg) { Args.ArgumentMarshaler am = marshalers.get(arg); try { return am == null ? 0 : (Integer) am.get(); } catch (Exception e) { return 0; } } public boolean has(char arg) { return argsFound.contains(arg); } public boolean isValid() { return valid; } private class ArgsException extends Exception { } private abstract class ArgumentMarshaler { public abstract void set(String s) throws ArgsException; public abstract Object get(); } private class BooleanArgumentMarshaler extends ArgumentMarshaler { private boolean booleanValue = false; public void set(String s) { booleanValue = true; } public Object get() { return booleanValue; } } private class StringArgumentMarshaler extends ArgumentMarshaler { private String stringValue = ""; public void set(String s) { stringValue = s; } public Object get() { return stringValue; } } private class IntegerArgumentMarshaler extends ArgumentMarshaler { private int intValue = 0; public void set(String s) throws ArgsException { try { intValue = Integer.parseInt(s); } catch (NumberFormatException e) { throw new ArgsException(); } } public Object get() { return intValue; } } } 읽고나서 솔직히 java를 모르는 나는 이해할 리가 없지만.. 언젠가는.. ...

2023년 9월 11일 · 5 분 · 배준수

권한

책너두 6기 6일차 백은빈, 이성욱의 Real MySQL8.0 1권 p.65 ~ p.75 내용정리 03 사용자 및 권한 3.4 권한(privilege) 글로벌 권한 객체 권한 데이터베이스나 테이블이외의 객체에 적용 데이터베이스나 테이블을 제어하는데 필요 grant명령에서 특정 객체를 명시X 권한을 부여할 떄 반드시 특정 객체 명시 ALL(또는 all privileges) 글로벌과 객체 권한 두 가지 용도로 사용 될 수 있음. 특정 객체에 ALL 권한이 부여되면 해당 객체에 적용될 수 있는 모든 객체 권한을 부여 글로벌로 ALL이 사용되면 글로벌 수준에서 가능한 모든 권한 부여 ...

2023년 9월 9일 · 2 분 · 배준수

기술적 문제(1) 면접 준비하기

6일차 게일 라크만 맥도웰의 코딩 인터뷰 완전 분석 p.89 ~ p. 108 내용 정리 7. 기술적 문제 최고의 테크 회사들은 면접의 기초로 기술적 문제들을 삼는다. 준비하기 직접 풀도록 노력하라 : 직접 답을 찾도록 노력하고 포기하지 말자 코드를 종이에 적으라 : 코드 문법 강조, 코드 자동 완성 없는 것에 익숙해져보자. 코드를 테스트하라 : 종이에서 해야한다. 종이에 적은 코드를 그대로 컴퓨터로 옮긴 뒤 실제로 실행해 보라 : 어디에서 실수가 있었는지 체크하고 유의하자. 가상 면접 경험도 중요하다. ...

2023년 9월 9일 · 5 분 · 배준수

점진적인 개선(3)

책너두 5기 30일차 로버트 C. 마틴의 클린코드 p. 273~ p.288 내용정리 14. 점진적인 개선 String 인수 HashMap을 변경한 후 parse, set, get 함수를 고쳤다. 각 인수 유형을 처리하는 코드를 ArgumentMarshaler 클래스에 넣고 나서 ArgumentMarshaler 파생 클래스를 만들어 코드를 분리하는 것이 의도였다. 이 후 int 인수 기능을 ArgumentMarshaler로 옮겼다. 모든 논리를 ArgumentMarshaler로 옮긴 뒤 파생 클래스를 만들어 기능을 분산한다. setBoolean 함수를 BooleanArgumentMarshaler로 옮긴 후 올바로 호출되는지 확인한다. ArgumentMarshaler 클래스에 추상 메서드 set을 만든다. BooleanArgumentMarshaler 클래스에 set 메서드를 구현한다. sertBoolean 호출을 set 호출로 바꾼다. 테스트를 통과하면 ArgumentMarshaler에서 setBoolean 메서드를 제거한다. get 메서드를 BooleanArgumentMarshaler로 옮긴다. ArgumentMarshaler에서 get을 추상 메서드로 만든 후 BooleanArgumentMarshaler에 구현한다. ArgumentMarshaler에서 getBoolean 함수를 제거한 후 booleanValue를 BooleanArgumentMarshaler로 내려 private 변수로 선언한다. 같은 방식으로 Strings 인수 유형도 변경한다. 마지막으로 integer 인수 유형에도 같은 과정을 반복한다. 이제 isBooleanArg를 다음과 같이 변경한다 ...

2023년 9월 9일 · 2 분 · 배준수

파이썬 알고리즘 : 아주 평범한 배낭, 행렬 곱셈 순서, 가장 긴 증가하는 부분 수열

2023년 9월 9일 알고리즘 문제풀이 문제 1 백준 12865 문제 링크 1차 시도 나의 생각 입력값을 받을 때 무게 제한보다 무거운 물건은 아예 받지 않도록 조건을 추가한다. 큐를 이용한 최소힙을 통해 물건의 무게와 가치를 원소로 하는 배열에서 무게가 낮은 순서로 하나씩 pop한다. 배낭을 나타내는 배열에 [0,0]을 추가하여 아무것도 없는 상태를 만든다. pop할 때마다 기존 가방에 있는 것에 현재 물건을 더한 것을 추가해준다. 이 방식이면 원소갯수가 2배씩 늘어난다. 비어있는것 1개 => 첫번째 물건 더한것과 안더한것 2개 => 앞의 2개에 각각 두번째 물건을 더한것과 안더한 것 해서 총 4개 => 8개 => … ...

2023년 9월 9일 · 10 분 · 배준수

big-O

5일차 게일 라크만 맥도웰의 코딩 인터뷰 완전 분석 p.59 ~ p. 70 내용 정리 6. big-O big-O 시간은 알고리즘의 효율성을 나타내는 지표 혹은 언어이다. 비유하기 파일을 보낼 때 크기가 작다면 전송하는게 빠르지만 굉장히 크다면 물리적으로 직접 가는게 빠를것.(1테라를 미국에 메일로 보내느니 들고 비행기타고 가는게 낫다!) 시간 복잡도 점근적 실행 시간(asymptotic runtime), 또는 big-O 시간에 대한 개념에 대해 얘기해보자. 데이터 전송 ‘알고리즘’의 실행 시간에서 온라인 전송: O(s), s가 파일의 크기이다. 파일의 크기가 증가함에 따라 전송 시간 또한 선형적으로 증가 비행기 전송: O(1), 파일 크기랑 상관없다. 크든 작든 비행기 한대 가는 시간이니까! O(s)가 커지다 보면 어느 순간 O(1)보다 커지게 된다. O(1)이 얼마든, O(s)가 얼마나 천천히 커지든 언젠가는 무조건! ...

2023년 9월 8일 · 12 분 · 배준수

사용자 식별

책너두 6기 5일차 백은빈, 이성욱의 Real MySQL8.0 1권 p.52 ~ p.64 5일차 03 사용자 및 권한 MySQL에서 사용자 계정을 생성하는 방법이나 각 계정의 권한을 설정하는 방법은 다른 DBMS와 차이 가 있음. MySQL은 ID 뿐 아니라 접속 IP도 확인함. Role로 권한을 묶는 개념이 있음 3.1 사용자 식별 MySQL의 사용자는 계정뿐 아니라 접속 지점(호스트명이나 도메인 또는 IP 주소)도 계정의 일부가 됌. 따라서 계정을 언급할 때 아이디와 호스트를 함께 명시 백슬래시(`)는 식별자를 감싸는 따옴표 역할을 하는데 홑따옴표(’)로 바뀌어서 사용되기도 함 ...

2023년 9월 8일 · 6 분 · 배준수

점진적인 개선(2)

책너두 5기 29일차 로버트 C. 마틴의 클린코드 p. 255~ p.272 내용정리 14. 점진적인 개선 초안 작성 Args.java (Boolean만 지원하는 버전) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 package com.objectmentor.utilities.getopts; import java.util.*; public class Args { private String schema; private String[] args; private boolean valid; private Set<Character> unexpectedArguments = new TreeSet<Character>(); private Map<Character, Boolean> booleanArgs = new HashMap<Character, Boolean>(); private int numberOfArguments = 0; public Args(String schema, String[] args) { this.schema = schema; this.args = args; valid = parse(); } public boolean isValid() { return valid; } private boolean parse() { if (schema.length() == 0 && args.length == 0) return true; parseSchema(); parseArguments(); return unexpectedArguments.size() == 0; } private boolean parseSchema() { for (String element : schema.split(”,”)) { parseSchemaElement(element); } return true; } private void parseSchemaElement(String element) { if (element.length() == 1) { parseBooleanSchemaElement(element); } } private void parseBooleanSchemaElement(String element) { char c = element.charAt(0); if (Character.isLetter(c)) { booleanArgs.put(c, false); } } private boolean parseArguments() { for (String arg : args) parseArgument(arg); return true; } private void parseArgument(String arg) { if (arg.startsWith(”-”)) parseElements(arg); } private void parseElements(String arg) { for (int i = 1; i < arg.length(); i++) parseElement(arg.charAt(i)); } private void parseElement(char argChar) { if (isBoolean(argChar)) { numberOfArguments++; setBooleanArg(argChar, true); } else unexpectedArguments.add(argChar); } private void setBooleanArg(char argChar, boolean value) { booleanArgs.put(argChar, value); } private boolean isBoolean(char argChar) { return booleanArgs.containsKey(argChar); } public int cardinality() { return numberOfArguments; } public String usage() { if (schema.length() > 0) return ”-[“+schema+”]”; else return ””; } public String errorMessage() { if (unexpectedArguments.size() > 0) { return unexpectedArgumentMessage(); } else return ””; } private String unexpectedArgumentMessage() { StringBuffer message = new StringBuffer(“Argument(s) -”); for (char c : unexpectedArguments) { message.append(c); } message.append(“ unexpected.”); return message.toString(); } public boolean getBoolean(char arg) { return booleanArgs.get(arg); } } 가장 초기의 코드. 우선 String 인수 유형을 추가하여 아래 코드가 된다. ...

2023년 9월 8일 · 8 분 · 배준수

파이썬 알고리즘 : 정제헌을 팔자!, LCS, LCS2

2023년 9월 8일 알고리즘 문제풀이 문제 1 백준 9273 문제 링크 1차 시도 나의 생각 결국 두 자연수 a,b에 대하여 1/n = 1/a + 1/b 가 성립해야 한다고 생각했다. 따라서 이 수식을 고쳐서 b = na/(a-n) 으로 만들었다. 이 함수를 a,b 에 대한 함수로 이해해보자. b-n = (n^2)/(a-n). 유리함수중에 분수 함수라고 할 수 있다. 점근선은 x =n, y = n이다. 아래와 같은 함수이다. 이 그래프에서 x,y가 모두 자연수인 함수 위 좌표를 찾았다. x가 0일 때 y가 n이다. x가 1이면 y는 자연수일 수 없다. 따라서 x가 2부터 1씩 증가하다가 y값이 음수면 멈췄다. ...

2023년 9월 8일 · 7 분 · 배준수