diff --git a/src/main/java/org/nhnacademy/App.java b/src/main/java/org/nhnacademy/App.java deleted file mode 100644 index 73e4ef9..0000000 --- a/src/main/java/org/nhnacademy/App.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.nhnacademy; - -/** - * Hello world! - * - */ -public class App -{ - public static void main( String[] args ) - { - System.out.println( "Hello World!" ); - } -} diff --git a/src/main/java/org/nhnacademy/lsj/Main.java b/src/main/java/org/nhnacademy/lsj/Main.java new file mode 100644 index 0000000..1151d87 --- /dev/null +++ b/src/main/java/org/nhnacademy/lsj/Main.java @@ -0,0 +1,16 @@ +package org.nhnacademy.lsj; + +public class Main { + + public static void main(String[] args) { + + //Problem1.problem1(); + //Problem2.problem2(); + Problem3.problem3(); + //Problem4.problem4(); + //Problem5.problem5(); + //Problem6.problem6(); + + } + +} diff --git a/src/main/java/org/nhnacademy/lsj/Parser.java b/src/main/java/org/nhnacademy/lsj/Parser.java new file mode 100644 index 0000000..30b6cf7 --- /dev/null +++ b/src/main/java/org/nhnacademy/lsj/Parser.java @@ -0,0 +1,274 @@ +package org.nhnacademy.lsj; + +import textio.TextIO; + +/** + This program reads standard expressions typed in by the user. + The program constructs an expression tree to represent the + expression. It then prints the value of the tree. It also uses + the tree to print out a list of commands that could be used + on a stack machine to evaluate the expression. + The expressions can use positive real numbers and + the binary operators +, -, *, and /. The unary minus operation + is supported. The expressions are defined by the BNF rules: + + ::= [ "-" ] [ [ "+" | "-" ] ]... + + ::= [ [ "*" | "/" ] ]... + + ::= | "(" ")" + + A number must begin with a digit (i.e., not a decimal point). + A line of input must contain exactly one such expression. If extra + data is found on a line after an expression has been read, it is + considered an error. + + In addition to the main program class, SimpleParser3, this program + defines a set of four nested classes for implementing expression trees. + + */ + +public class Parser { + + // -------------------- Nested classes for Expression Trees ------------------------------ + + + /** + * An abstract class representing any node in an expression tree. + * The three concrete node classes are concrete subclasses. + * Two instance methods are specified, so that they can be used with + * any ExpNode. The value() method returns the value of the + * expression. The printStackCommands() method prints a list + * of commands that could be used to evaluate the expression on + * a stack machine (assuming that the value of the expression is + * to be left on the stack). + */ + abstract private static class ExpNode { + abstract double value(); + abstract void printStackCommands(); + } + + /** + * Represents an expression node that holds a number. + */ + private static class ConstNode extends ExpNode { + double number; // The number. + ConstNode(double val) { + // Construct a ConstNode containing the specified number. + number = val; + } + double value() { + // The value of the node is the number that it contains. + return number; + } + void printStackCommands() { + // On a stack machine, just push the number onto the stack. + System.out.println(" Push " + number); + } + } + + + /** + * An expression node representing a binary operator. + */ + private static class BinOpNode extends ExpNode { + char op; // The operator. + ExpNode left; // The expression for its left operand. + ExpNode right; // The expression for its right operand. + BinOpNode(char op, ExpNode left, ExpNode right) { + // Construct a BinOpNode containing the specified data. + assert op == '+' || op == '-' || op == '*' || op == '/'; + assert left != null && right != null; + this.op = op; + this.left = left; + this.right = right; + } + double value() { + // The value is obtained by evaluating the left and right + // operands and combining the values with the operator. + double x = left.value(); + double y = right.value(); + switch (op) { + case '+': return x + y; + case '-': return x - y; + case '*': return x * y; + case '/': return x / y; + default: return Double.NaN; // Bad operator! + } + } + void printStackCommands() { + // To evaluate the expression on a stack machine, first do + // whatever is necessary to evaluate the left operand, leaving + // the answer on the stack. Then do the same thing for the + // second operand. Then apply the operator (which means popping + // the operands, applying the operator, and pushing the result). + left.printStackCommands(); + right.printStackCommands(); + System.out.println(" Operator " + op); + } + } + + + /** + * An expression node to represent a unary minus operator. + */ + private static class UnaryMinusNode extends ExpNode { + ExpNode operand; // The operand to which the unary minus applies. + UnaryMinusNode(ExpNode operand) { + // Construct a UnaryMinusNode with the specified operand. + assert operand != null; + this.operand = operand; + } + double value() { + // The value is the negative of the value of the operand. + double neg = operand.value(); + return -neg; + } + void printStackCommands() { + // To evaluate this expression on a stack machine, first do + // whatever is necessary to evaluate the operand, leaving the + // operand on the stack. Then apply the unary minus (which means + // popping the operand, negating it, and pushing the result). + operand.printStackCommands(); + System.out.println(" Unary minus"); + } + } + + + // ------------------------------------------------------------------------------- + + + /** + * An object of type ParseError represents a syntax error found in + * the user's input. + */ + private static class ParseError extends Exception { + ParseError(String message) { + super(message); + } + } // end nested class ParseError + + + public static void main(String[] args) { + + while (true) { + System.out.println("\n\nEnter an expression, or press return to end."); + System.out.print("\n? "); + TextIO.skipBlanks(); + if ( TextIO.peek() == '\n' ) + break; + try { + ExpNode exp = expressionTree(); + TextIO.skipBlanks(); + if ( TextIO.peek() != '\n' ) + throw new ParseError("Extra data after end of expression."); + TextIO.getln(); + System.out.println("\nValue is " + exp.value()); + System.out.println("\nOrder of postfix evaluation is:\n"); + exp.printStackCommands(); + } + catch (ParseError e) { + System.out.println("\n*** Error in input: " + e.getMessage()); + System.out.println("*** Discarding input: " + TextIO.getln()); + } + } + + System.out.println("\n\nDone."); + + } // end main() + + + /** + * Reads an expression from the current line of input and builds + * an expression tree that represents the expression. + * @return an ExpNode which is a pointer to the root node of the + * expression tree + * @throws ParseError if a syntax error is found in the input + */ + private static ExpNode expressionTree() throws ParseError { + TextIO.skipBlanks(); + boolean negative; // True if there is a leading minus sign. + negative = false; + if (TextIO.peek() == '-') { + TextIO.getAnyChar(); + negative = true; + } + ExpNode exp; // The expression tree for the expression. + exp = termTree(); // Start with the first term. + if (negative) + exp = new UnaryMinusNode(exp); + TextIO.skipBlanks(); + while ( TextIO.peek() == '+' || TextIO.peek() == '-' ) { + // Read the next term and combine it with the + // previous terms into a bigger expression tree. + char op = TextIO.getAnyChar(); + ExpNode nextTerm = termTree(); + exp = new BinOpNode(op, exp, nextTerm); + TextIO.skipBlanks(); + } + return exp; + } // end expressionTree() + + + /** + * Reads a term from the current line of input and builds + * an expression tree that represents the expression. + * @return an ExpNode which is a pointer to the root node of the + * expression tree + * @throws ParseError if a syntax error is found in the input + */ + private static ExpNode termTree() throws ParseError { + TextIO.skipBlanks(); + ExpNode term; // The expression tree representing the term. + term = factorTree(); + TextIO.skipBlanks(); + while ( TextIO.peek() == '*' || TextIO.peek() == '/' ) { + // Read the next factor, and combine it with the + // previous factors into a bigger expression tree. + char op = TextIO.getAnyChar(); + ExpNode nextFactor = factorTree(); + term = new BinOpNode(op,term,nextFactor); + TextIO.skipBlanks(); + } + return term; + } // end termValue() + + + /** + * Reads a factor from the current line of input and builds + * an expression tree that represents the expression. + * @return an ExpNode which is a pointer to the root node of the + * expression tree + * @throws ParseError if a syntax error is found in the input + */ + private static ExpNode factorTree() throws ParseError { + TextIO.skipBlanks(); + char ch = TextIO.peek(); + if ( Character.isDigit(ch) ) { + // The factor is a number. Return a ConstNode. + double num = TextIO.getDouble(); + return new ConstNode(num); + } + else if ( ch == '(' ) { + // The factor is an expression in parentheses. + // Return a tree representing that expression. + TextIO.getAnyChar(); // Read the "(" + ExpNode exp = expressionTree(); + TextIO.skipBlanks(); + if ( TextIO.peek() != ')' ) + throw new ParseError("Missing right parenthesis."); + TextIO.getAnyChar(); // Read the ")" + return exp; + } + else if ( ch == '\n' ) + throw new ParseError("End-of-line encountered in the middle of an expression."); + else if ( ch == ')' ) + throw new ParseError("Extra right parenthesis."); + else if ( ch == '+' || ch == '-' || ch == '*' || ch == '/' ) + throw new ParseError("Misplaced operator."); + else + throw new ParseError("Unexpected character \"" + ch + "\" encountered."); + } // end factorTree() + + +} // end class SimpleParser3 \ No newline at end of file diff --git a/src/main/java/org/nhnacademy/lsj/Problem1.java b/src/main/java/org/nhnacademy/lsj/Problem1.java new file mode 100644 index 0000000..24ca6e8 --- /dev/null +++ b/src/main/java/org/nhnacademy/lsj/Problem1.java @@ -0,0 +1,66 @@ +package org.nhnacademy.lsj; + +import java.math.BigInteger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 피보나치를 실행함. + * 피보나치 조건 f(0) = 1 , f(1) = 1 , f(n) = f(n-1) + f(n-2) . + */ + +public class Problem1 { + + private static final Logger logger = LoggerFactory.getLogger(Problem1.class); + + /** + * 재귀로 구현한 피보나치 함수. + * + * @param number 피보나치 함수 f(N). + * @return f(N)의 리턴값. + */ + public static BigInteger fibonacci(BigInteger number) { + + if (number.equals(BigInteger.ZERO)) { + return BigInteger.ONE; + } else if (number.equals(BigInteger.ONE)) { + return BigInteger.ONE; + } + + return fibonacci(number.subtract(BigInteger.ONE)) + .add(fibonacci(number.subtract(BigInteger.TWO))); + } + + public static BigInteger factorial(BigInteger number) { + + if (number.equals(BigInteger.ZERO)) { + return BigInteger.ONE; + } + + return number.multiply(factorial(number.subtract(BigInteger.ONE))); + + } + + + /** + * f(1) ... f(10) 까지의 피보나치 . + */ + public static void problem1() { + + + for (int i = 0; i <= 10; i++) { + logger.info("{}", fibonacci(new BigInteger(String.valueOf(i)))); + } + + for (int i = 0; i <= 10; i++) { + logger.info("{}", factorial(new BigInteger(String.valueOf(i)))); + } + + } + +} + + +/** + * + */ diff --git a/src/main/java/org/nhnacademy/lsj/Problem2.java b/src/main/java/org/nhnacademy/lsj/Problem2.java new file mode 100644 index 0000000..145bcb3 --- /dev/null +++ b/src/main/java/org/nhnacademy/lsj/Problem2.java @@ -0,0 +1,151 @@ +package org.nhnacademy.lsj; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.StringTokenizer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * resources 에 있는 lsj.txt를 읽어 . + * 파일에 나오는 모든 단어를 이진 정렬트리에 넣는 프로그램. + */ +public class Problem2 { + + + private static final Logger logger = LoggerFactory.getLogger(Problem2.class); + + + /** + * br을 통해서 txt 읽음 , StringTokenizer를 통해 공백 제거 후 이진 정렬트리에 넣어줌. + * 이진정렬 트리의 add는 메서드로 구현돼있음 , 자동으로 정렬돼서 들어감. + */ + public static void problem2() { + + BinarySearchTree bst = null; + + + try (BufferedReader br = new BufferedReader(new FileReader("src/main/resources/lsj.txt"))) { + + StringTokenizer stk; + String line; + + while ((line = br.readLine()) != null) { + stk = new StringTokenizer(line); + while (stk.hasMoreTokens()) { + + String str = stk.nextToken(); + + if (bst == null) { + bst = new BinarySearchTree(str); + continue; + } + + bst.add(bst, str); + } + } + + } catch (IOException e) { + logger.info("읽을 파일이 존재하지 않습니다.\n프로그램을 종료합니다"); + return; + } + + BinarySearchTree.printPreOrder(bst); + + + } + +} + +class BinarySearchTree { + + private static final Logger logger = LoggerFactory.getLogger(BinarySearchTree.class); + + + private BinarySearchTree left; + + private BinarySearchTree right; + + private String value; + + + public String getValue() { + return value; + } + + public BinarySearchTree getLeft() { + return left; + } + + public BinarySearchTree getRight() { + return right; + } + + + public BinarySearchTree(String str) { + this.value = str; + this.left = null; + this.right = null; + } + + /** + * value가 왔을때 + * root 보다 작으면 == 즉 root아스키코드가 더 크면 -> 지금 들어온 value가 알파벳 선순위임 + * 선순위는 left로. + * root 보다 크면 == 즉 root아스키코드가 더 작으면 -> 지금 들어오면 value가 알파벳 후순위임 + * 후순위는 right로/ + * + * @param bst 이진정렬트리 . + * @param value add할 value. + */ + public void add(BinarySearchTree bst, String value) { + + + String temp = bst.getValue(); + + String temp2 = temp.toLowerCase(); // 정렬하기위해 소문자로 통일 ! + String value2 = value.toLowerCase(); + + + if (temp2.compareTo(value2) > 0) { // 아스키가 내가 더 커 + if (bst.left != null) { + add(bst.left, value); + } else { + bst.left = new BinarySearchTree(value); + + } + } else if (temp2.compareTo(value2) < 0) { // 아스키가 내가 더 작아 + + if (bst.right != null) { + add(bst.right, value); + + } else { + bst.right = new BinarySearchTree(value); + + } + + } + + } + + + /** + * preOrder 순회 . + * + * @param bst 이진정렬트리. + */ + public static void printPreOrder(BinarySearchTree bst) { + + if (bst == null) { + return; + } + logger.info("{}", bst.value); + + printPreOrder(bst.left); + printPreOrder(bst.right); + + } + + +} \ No newline at end of file diff --git a/src/main/java/org/nhnacademy/lsj/Problem3.java b/src/main/java/org/nhnacademy/lsj/Problem3.java new file mode 100644 index 0000000..587cd6d --- /dev/null +++ b/src/main/java/org/nhnacademy/lsj/Problem3.java @@ -0,0 +1,188 @@ +package org.nhnacademy.lsj; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 연결리스트를 만든 후 그 리스트의 reverse를 저장하는 프로그램. + */ +public class Problem3 { + + + private static final Logger logger = LoggerFactory.getLogger(Problem3.class); + + /** + * addNode를 통해서 리스트의 끝에 원소 넣어줌. + * reverseListNode 메서드를 통해 reverseList 만듦. + * reverseListNode 메서드는 내부적으로 getNodeByIndex 메서드 사용하는데. + * 이는 List의 특정 index를 return 하는 메서드 . + * 이를통해서 순차적으로 끝에서부터 처음 head까지 넣어준다. + */ + public static void problem3() { + + + // ListNode listNode = new ListNode(0); + + +// for (int i = 1; i <= 10; i++) { +// addNode(listNode, new ListNode(i)); +// } + + ListNode listNode = addAllNode(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + + printListNode(listNode); + + ListNode answer = reverseListNode(listNode); + + + printListNode(answer); + + + } + + /** + * 역방향 List만드는 메서드 . + * getNodeByIndex를 통해서 맨 끝부터 , 맨 처음 head까지 넣어줌. + * + * @param listNode reverseList를 만들 기준이 되는 기존 list. + * @return reverseList. + */ + public static ListNode reverseListNode(ListNode listNode) { + + ListNode answer = null; + + int index = listNode.getListSize(); + + for (int i = index; i > 0; i--) { + + if (answer == null) { + answer = getNodeByIndex(listNode, i); + continue; + } + + addNode(answer, getNodeByIndex(listNode, i)); + } + + return answer; + + } + + /** + * List의 index번째 node를 반환함. get메서드와 같음. + * + * @param listNode 기준이되는 list. + * @param index 반환할 index. + * @return index번째 list . + */ + public static ListNode getNodeByIndex(ListNode listNode, int index) { + + // 이거 index가 음수인 경우에는 에러 터쳐줘야 함 + + if (index < 0) { + throw new IllegalArgumentException("0보다 작은 index는 올 수 없습니다."); + } + + + for (int i = 0; i < index - 1; i++) { + listNode = listNode.getNext(); + } + + return new ListNode(listNode.getItem()); + + } + + /** + * List에 node를 추가하는 메서드 , next가 더 존재하지 않을때 까지 가서 추가된다. + * + * @param listNode 추가될 List. + * @param node 추가될 노드. + */ + public static void addNode(ListNode listNode, ListNode node) { + + while (listNode.getNext() != null) { + listNode = listNode.getNext(); + } + listNode.setNext(node); + } + + /** + * List를 출력한다. + * List의 next가 존재하지 않을 때 까지 next로 보냄. + * + * @param listNode 출력할 List. + */ + public static void printListNode(ListNode listNode) { + + while (listNode != null) { + logger.info("{}", listNode.getItem()); + listNode = listNode.getNext(); + } + + } + + + public static ListNode addAllNode(int... num) { + + ListNode head = null; + ListNode start = null; + + for (int i = 0; i < num.length; i++) { + + if (head == null) { + head = new ListNode(num[i]); + start = head; + continue; + } + + while (head.getNext() != null) { + head = head.getNext(); + } + + head.setNext(new ListNode(num[i])); + + } + return start; + + } + + +} + + +class ListNode { + + private int item; + private ListNode next; + + public ListNode(int item) { + this.item = item; + this.next = null; + } + + public int getItem() { + return item; + } + + public ListNode getNext() { + return this.next; + } + + public void setNext(ListNode listNode) { + this.next = listNode; + } + + public int getListSize() { + + int count = 0; + + ListNode listNode = this; + + while (listNode != null) { + count++; + listNode = listNode.getNext(); + } + return count; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/nhnacademy/lsj/Problem4.java b/src/main/java/org/nhnacademy/lsj/Problem4.java new file mode 100644 index 0000000..f892b9e --- /dev/null +++ b/src/main/java/org/nhnacademy/lsj/Problem4.java @@ -0,0 +1,73 @@ +package org.nhnacademy.lsj; + +import java.util.LinkedList; +import java.util.Queue; +import java.util.Scanner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 큐를 사용한 이진트리 출력 프로그램. + */ +public class Problem4 { + + + private static final Logger logger = LoggerFactory.getLogger(Problem4.class); + + + /** + * a s t v b c d 넣어서 postCondition Check 완료했음. + * 이진트리 생성 -> add 완료 -> Queue를 만든다 -> bfs통해서 tree요소들 print하기. + */ + public static void problem4() { + Queue q = new LinkedList<>(); + + Scanner sc = new Scanner(System.in); + + BinarySearchTree bst = new BinarySearchTree("root"); + + + for (int i = 0; i < 7; i++) { + bst.add(bst, sc.nextLine()); + } + + q.add(bst); + + bfs(q); + + + } + + /** + * queue 에 root를 넣은채로 온다 -> q를 poll 함 -> poll 한거 출력해. + * -> 그게 root , 얘가 left 존재하면 q에 넣어 , right 존재하면 q에 넣어. + * 이 행동 반복해. + * + * @param q bfs를 돌릴 queue. + */ + public static void bfs(Queue q) { + + + while (!q.isEmpty()) { + + BinarySearchTree temp = q.poll(); + + + logger.info("{}", temp.getValue()); + + if (temp.getLeft() != null) { + q.add(temp.getLeft()); + } + + if (temp.getRight() != null) { + q.add(temp.getRight()); + } + + } + + + } + + +} + diff --git a/src/main/java/org/nhnacademy/lsj/Problem5.java b/src/main/java/org/nhnacademy/lsj/Problem5.java new file mode 100644 index 0000000..c10d98f --- /dev/null +++ b/src/main/java/org/nhnacademy/lsj/Problem5.java @@ -0,0 +1,192 @@ +package org.nhnacademy.lsj; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 이진트리는 어느정도 벨런스가 잡혀있음. + * 이전에 만들어 놧던 이진 트리를 이용해서. + * 1023개의 노드가 있는 트리를 만듦. + * 그리고 모든 리프노드의 평균 깊이 , 가장 큰 리프노드 깊이 , 리프노드의 개수 를 찾음. + */ +public class Problem5 { + + private static final Logger logger = LoggerFactory.getLogger(Problem5.class); + + /** + * 이진정렬트리 만듦 -> 값은 랜덤으로 1~300사이의 실수로 넣어줄꺼야. + * 이거 자동정렬됨 , 구현은 Problem2와 같음. + * 이제 tree 순회하면서 leafNode 개수 체크하고 , 더하고 , Max값 찾을꺼임. + */ + public static void problem5() { + + + BinarySearchTreeNumber bstn = new BinarySearchTreeNumber(150); + + + for (int i = 1; i < 1023; i++) { + double num = Math.random() * 300 + 1; + bstn.add(bstn, (Math.random() * 300 + 1)); + } + + BinarySearchTreeNumber.printPreOrderNumber(bstn); + + logger.info("leaf depth 합 {}", BinarySearchTreeNumber.sumLeafNodeDepth(bstn, 0)); + + logger.info("leaf Average depth {}", BinarySearchTreeNumber.sumLeafNodeDepth(bstn, 0) + / BinarySearchTreeNumber.countLeafNode(bstn)); + + logger.info("leaf Max Depth {}", BinarySearchTreeNumber.getMaxDepth(bstn, 0)); + + + } + +} + + +class BinarySearchTreeNumber { + + private static final Logger logger = LoggerFactory.getLogger(BinarySearchTree.class); + + + private BinarySearchTreeNumber left; + + private BinarySearchTreeNumber right; + + private double value; + + public double getValue() { + return value; + } + + public BinarySearchTreeNumber getLeft() { + return left; + } + + public BinarySearchTreeNumber getRight() { + return right; + } + + + public BinarySearchTreeNumber(double number) { + this.value = number; + this.left = null; + this.right = null; + } + + /** + * value가 왔을때. + * root 보다 작으면 == left로 + * root 보다 크면 == right로 + * + * @param bst 이진정렬트리 . + * @param value add할 value. + */ + public void add(BinarySearchTreeNumber bst, double value) { + + + double temp = bst.getValue(); + + + if (temp - value > 0) { // 내가 더 커 -> 그럼 left에 + if (bst.left != null) { + add(bst.left, value); + + } else { + bst.left = new BinarySearchTreeNumber(value); + + } + } else if (temp - value < 0) { // 내가 더 작아 -> 그럼 right로 + + if (bst.right != null) { + add(bst.right, value); + + } else { + bst.right = new BinarySearchTreeNumber(value); + + } + + } + + } + + + /** + * preOrder 순회 . + * + * @param bst 이진정렬트리. + */ + public static void printPreOrderNumber(BinarySearchTreeNumber bst) { + + if (bst == null) { + return; + } + logger.info("{}", bst.value); + + printPreOrderNumber(bst.left); + printPreOrderNumber(bst.right); + + } + + public static int countLeafNode(BinarySearchTreeNumber bst) { + + int count = 0; + + if (bst.left == null && bst.right == null) { + return 1; + } + + if (bst.left != null) { + count += countLeafNode(bst.left); + } + + if (bst.right != null) { + count += countLeafNode(bst.right); + } + + return count; + + } + + public static int getMaxDepth(BinarySearchTreeNumber bst, int depth) { + + int maxDepth = 0; + + if (bst.left == null && bst.right == null) { // leaf 노드면 + return depth; + } + + if (bst.left != null) { + maxDepth = Math.max(maxDepth, getMaxDepth(bst.left, depth + 1)); + } + + if (bst.right != null) { + maxDepth = Math.max(maxDepth, getMaxDepth(bst.right, depth + 1)); + } + + return maxDepth; + + } + + public static int sumLeafNodeDepth(BinarySearchTreeNumber bst, int depth) { + + int depthSum = 0; + + if (bst.left == null && bst.right == null) { // leaf 노드면 + return depth; + } + + if (bst.left != null) { + depthSum += sumLeafNodeDepth(bst.left, depth + 1); + } + + if (bst.right != null) { + depthSum += sumLeafNodeDepth(bst.right, depth + 1); + } + + return depthSum; + + } + + +} diff --git a/src/main/java/org/nhnacademy/lsj/Problem6.java b/src/main/java/org/nhnacademy/lsj/Problem6.java new file mode 100644 index 0000000..bb1d0f9 --- /dev/null +++ b/src/main/java/org/nhnacademy/lsj/Problem6.java @@ -0,0 +1,338 @@ +package org.nhnacademy.lsj; + +import textio.TextIO; + +public class Problem6 { + + + public static void problem6() { + + + SimpleParser3 simpleParser3 = new SimpleParser3(); + + + } + +} + + +/** + * This program reads standard expressions typed in by the user. + * The program constructs an expression tree to represent the + * expression. It then prints the value of the tree. It also uses + * the tree to print out a list of commands that could be used + * on a stack machine to evaluate the expression. + * The expressions can use positive real numbers and + * the binary operators +, -, *, and /. The unary minus operation + * is supported. The expressions are defined by the BNF rules: + * + * ::= [ "-" ] [ [ "+" | "-" ] ]... + * + * ::= [ [ "*" | "/" ] ]... + * + * ::= | "(" ")" + *

+ * A number must begin with a digit (i.e., not a decimal point). + * A line of input must contain exactly one such expression. If extra + * data is found on a line after an expression has been read, it is + * considered an error. + *

+ * In addition to the main program class, SimpleParser3, this program + * defines a set of four nested classes for implementing expression trees. + */ + +class SimpleParser3 { + + // -------------------- Nested classes for Expression Trees ------------------------------ + + + /** + * An abstract class representing any node in an expression tree. + * The three concrete node classes are concrete subclasses. + * Two instance methods are specified, so that they can be used with + * any ExpNode. The value() method returns the value of the + * expression. The printStackCommands() method prints a list + * of commands that could be used to evaluate the expression on + * a stack machine (assuming that the value of the expression is + * to be left on the stack). + */ + abstract private static class ExpNode { + abstract double value(double xValue); + + abstract void printStackCommands(); + } + + /** + * An expression node representing a binary operator. + */ + /** + * Represents an expression node that holds a number. + */ + private static class ConstNode extends ExpNode { + double number; // The number. + + ConstNode(double val) { + // Construct a ConstNode containing the specified number. + number = val; + } + + double value(double xValue) { + // The value of the node is the number that it contains. + return number; + } + + void printStackCommands() { + // On a stack machine, just push the number onto the stack. + System.out.println(" Push " + number); + } + } + + + /** + * An expression node representing a binary operator, + */ + private static class BinOpNode extends ExpNode { + char op; // The operator. + ExpNode left; // The expression for its left operand. + ExpNode right; // The expression for its right operand. + + BinOpNode(char op, ExpNode left, ExpNode right) { + // Construct a BinOpNode containing the specified data. + assert op == '+' || op == '-' || op == '*' || op == '/'; + assert left != null && right != null; + this.op = op; + this.left = left; + this.right = right; + } + + double value(double xValue) { + // The value is obtained by evaluating the left and right + // operands and combining the values with the operator. + double x = left.value(xValue); + double y = right.value(xValue); + switch (op) { + case '+': + return x + y; + case '-': + return x - y; + case '*': + return x * y; + case '/': + return x / y; + default: + return Double.NaN; // Bad operator! + } + } + + void printStackCommands() { + // To evaluate the expression on a stack machine, first do + // whatever is necessary to evaluate the left operand, leaving + // the answer on the stack. Then do the same thing for the + // second operand. Then apply the operator (which means popping + // the operands, applying the operator, and pushing the result). + left.printStackCommands(); + right.printStackCommands(); + System.out.println(" Operator " + op); + } + } + + + /** + * An expression node to represent a unary minus operator. + */ + private static class UnaryMinusNode extends ExpNode { + ExpNode operand; // The operand to which the unary minus applies. + + UnaryMinusNode(ExpNode operand) { + // Construct a UnaryMinusNode with the specified operand. + assert operand != null; + this.operand = operand; + } + + double value(double xValue) { + // The value is the negative of the value of the operand. + double neg = operand.value(xValue); + return -neg; + } + + void printStackCommands() { + // To evaluate this expression on a stack machine, first do + // whatever is necessary to evaluate the operand, leaving the + // operand on the stack. Then apply the unary minus (which means + // popping the operand, negating it, and pushing the result). + operand.printStackCommands(); + System.out.println(" Unary minus"); + } + } + + + /** + * An expression node that represents a reference to the variable, x. + */ + private static class VariableNode extends ExpNode { + VariableNode() { + // Construct a VariableNode. (There is nothing to do!) + } + + double value(double xValue) { + // The value of the node is the value of x. + return xValue; + } + + void printStackCommands() { + // On a stack machine, just push the value of X onto the stack. + System.out.println(" Push X"); + } + } + + +// ------------------------------------------------------------------------------- + + + /** + * An object of type ParseError represents a syntax error found in + * the user's input. + */ + private static class ParseError extends Exception { + ParseError(String message) { + super(message); + } + } // end nested class ParseError + + + public static void main(String[] args) { + + while (true) { + System.out.println("\n\nEnter an expression, or press return to end."); + System.out.print("\n? "); + TextIO.skipBlanks(); + if (TextIO.peek() == '\n') { + break; + } + try { + ExpNode exp = expressionTree(); + TextIO.skipBlanks(); + if (TextIO.peek() != '\n') { + throw new ParseError("Extra data after end of expression."); + } + TextIO.getln(); + System.out.println("\nValue at x = 0 is " + exp.value(0)); + System.out.println("Value at x = 1 is " + exp.value(1)); + System.out.println("Value at x = 2 is " + exp.value(2)); + System.out.println("Value at x = 3 is " + exp.value(3)); + System.out.println("\nOrder of postfix evaluation is:\n"); + exp.printStackCommands(); + } catch (ParseError e) { + System.out.println("\n*** Error in input: " + e.getMessage()); + System.out.println("*** Discarding input: " + TextIO.getln()); + } + } + + System.out.println("\n\nDone."); + + } // end main() + + + /** + * Reads an expression from the current line of input and builds + * an expression tree that represents the expression. + * + * @return an ExpNode which is a pointer to the root node of the + * expression tree + * @throws ParseError if a syntax error is found in the input + */ + private static ExpNode expressionTree() throws ParseError { + TextIO.skipBlanks(); + boolean negative; // True if there is a leading minus sign. + negative = false; + if (TextIO.peek() == '-') { + TextIO.getAnyChar(); + negative = true; + } + ExpNode exp; // The expression tree for the expression. + exp = termTree(); // Start with the first term. + if (negative) { + exp = new UnaryMinusNode(exp); + } + TextIO.skipBlanks(); + while (TextIO.peek() == '+' || TextIO.peek() == '-') { + // Read the next term and combine it with the + // previous terms into a bigger expression tree. + char op = TextIO.getAnyChar(); + ExpNode nextTerm = termTree(); + exp = new BinOpNode(op, exp, nextTerm); + TextIO.skipBlanks(); + } + return exp; + } // end expressionTree() + + + /** + * Reads a term from the current line of input and builds + * an expression tree that represents the expression. + * + * @return an ExpNode which is a pointer to the root node of the + * expression tree + * @throws ParseError if a syntax error is found in the input + */ + private static ExpNode termTree() throws ParseError { + TextIO.skipBlanks(); + ExpNode term; // The expression tree representing the term. + term = factorTree(); + TextIO.skipBlanks(); + while (TextIO.peek() == '*' || TextIO.peek() == '/') { + // Read the next factor, and combine it with the + // previous factors into a bigger expression tree. + char op = TextIO.getAnyChar(); + ExpNode nextFactor = factorTree(); + term = new BinOpNode(op, term, nextFactor); + TextIO.skipBlanks(); + } + return term; + } // end termValue() + + + /** + * Reads a factor from the current line of input and builds + * an expression tree that represents the expression. + * + * @return an ExpNode which is a pointer to the root node of the + * expression tree + * @throws ParseError if a syntax error is found in the input + */ + + private static ExpNode factorTree() throws ParseError { + TextIO.skipBlanks(); + char ch = TextIO.peek(); + if (Character.isDigit(ch)) { + // The factor is a number. Return a ConstNode. + double num = TextIO.getDouble(); + return new ConstNode(num); + } else if (ch == 'x' || ch == 'X') { + // The factor is the variable x. + TextIO.getAnyChar(); // Read the X. + return new VariableNode(); + } else if (ch == '(') { + // The factor is an expression in parentheses. + // Return a tree representing that expression. + TextIO.getAnyChar(); // Read the "(" + ExpNode exp = expressionTree(); + TextIO.skipBlanks(); + if (TextIO.peek() != ')') { + throw new ParseError("Missing right parenthesis."); + } + TextIO.getAnyChar(); // Read the ")" + return exp; + } else if (ch == '\n') { + throw new ParseError("End-of-line encountered in the middle of an expression."); + } else if (ch == ')') { + throw new ParseError("Extra right parenthesis."); + } else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') { + throw new ParseError("Misplaced operator."); + } else { + throw new ParseError("Unexpected character \"" + ch + "\" encountered."); + } + } // end factorTree() + + +} // end class SimpleParser4 \ No newline at end of file diff --git "a/src/main/java/org/nhnacademy/lsj/\354\230\244\355\206\240\353\247\210\355\203\200\353\236\200" "b/src/main/java/org/nhnacademy/lsj/\354\230\244\355\206\240\353\247\210\355\203\200\353\236\200" new file mode 100644 index 0000000..2dba84d --- /dev/null +++ "b/src/main/java/org/nhnacademy/lsj/\354\230\244\355\206\240\353\247\210\355\203\200\353\236\200" @@ -0,0 +1,32 @@ + + +형식언어 = 특정한 법칙들에 따라 적절하게 구성된 문자열들의 집합 + +알파벳을 살펴보자 + +알파벳이란 a-z까지의 문자임 + +문자 하나하나를 의미해 + +그럼 문자열은?? + +알파벳에서 정의된 기호들을 나열한 유한 수열 (finite sequence)임 + +a , ca , ccba ,dddd 등이 문자열에 속함 + + +만약 다음과 같은 집합이 있다고 하자 + +Σ = (a,b,c) + +이 집합에서 만들어질 수 있는 문자열은 다음과 같다 + +Σ = { a,b,aa,ab,ba,bb,aaa,bbb,c,cc,....}는 무한언어 + +이 집합에 대해 만들어질 수 있는 모든 문자열들의 집합을 Σ = Closure 라고 한다. + + + + + + diff --git "a/src/main/java/org/nhnacademy/lsj/\354\261\225\355\204\2609\352\260\234\353\205\220.txt" "b/src/main/java/org/nhnacademy/lsj/\354\261\225\355\204\2609\352\260\234\353\205\220.txt" new file mode 100644 index 0000000..7db4854 --- /dev/null +++ "b/src/main/java/org/nhnacademy/lsj/\354\261\225\355\204\2609\352\260\234\353\205\220.txt" @@ -0,0 +1,353 @@ +Recursion + +재귀란 ? + +재귀 = 본인이 자기 자신을 호출할 수 있는 서브루틴을 의미 +Recursive Subroutine + +보통 재귀의 경우 계속해서 자기 자신을 호출하다가 + +특정한 base case 에서 본인 호출을 멈추는 식으로 구현이 된다. + + +Recursive Binary Search + +이진탐색의 경우 재귀적으로 구현이 가능함 + +start, end를 파라미터로 받고 +계속해서 start, end의 범위를 바꿔주면 됨 + +mid = start+end; +mid/=2; + +mid번째 요소가 내가 찾는 값보다 작으면 +함수를 다시 불러 BS(mid+1,end) + +값보다 커도 함수를 다시 불러 BS(start,mid-1) +이렇게 범위를 줄여나가는 것임 + +근데 무한 루프가 돌아갈수 있잖아?? + +그러니까 base case 즉 탈출할 case를 작성해줘 + +if(arr[mid]==내가찾는 값) 혹은 if(start>end) break; + +해주는거지 + + +또 재귀는 재귀없이도 풀수있지만 매우 복잡해지고 귀찮아지는 +몇몇 알고리즘들이 존재해 + +하노이타워 혹은 dfs알고리즘이 그래. + + +따라서 재귀는 일종의 테크닉이라고 보면 돼 +문제를 푸는데 유용한 테크닉 정도 + + +Linked Data Structures + + +재귀적인 클래스 정의또한 존재해 + + +public class Employee { + + String name; + + Employee supervisor; // 이게 상급자 +} + +이렇게 인스턴스 변수로 본인의 클래스 타입을 갖는 변수를 갖는거지 + +만약 가장 높은 사람이 누군지를 볼라면 + +supervisor가 null인 사람이 가장 높겠지? + +그러면 계속 재귀적으로 가는거야 + + while ( runner.supervisor != null ) { + count++; // Count the supervisor on this level. + runner = runner.supervisor; // Move up to the next level. + } 이렇게 계속해서 상급자 -> 상급자 -> 상급자 + +이런식으로 가는거지 + + +또 이런 애들은 linked list 로 구현이 돼있어 +변수 supervisor 가 Employee 를 타입으로 갖는 객체를 가르키고 + +이게 반복돼서 또 가르키고 , 가르키고.... 그러다 null을 가르키면 끝나는거지 + +이런걸 Linked Lists라고 해 + +주로 node라는 걸 통해서 말해 + +class Node { + String item; + Node next; +} + +이렇게 Node클래스가 Node타입의 인스턴스 변수를 갖는거지 + +그러면?? -> Node p; +p.next = new Node(무언가); 이런식으로 이어줄 수 있는거야 + + + Basic Linked List Processing + +일반적으로 Linked List는 처리할떄 맨 앞 노드 + +즉 head부터 시작해서 끝에있는 tail까지 가면서 작업을 처리해 + + +삽입을 하려면 head부터 시작해서 내가 삽입을 원하는 노드의 위치까지가 +p가 내가 원하는 노드의 위치라면 , 또 q가 내가 삽입을 원하는 노드라면 + +(p->prev)->next= q; +q->prev= p->prev; +q-> next = p; +p->prev = q + +이런식으로 이어지는거지 + +삭제도 비슷해 + + + +Stacks, Queues, and ADTs + + +Abstract Data Type = ADT라는게 존재해 + +ADT는 내부적인 연산 구현과 값들이 어떻게 표현되는지에 대한 +명시없이 쓸수있는 가능한 값들과 연산의 집합을 의미해 + +우리는 다양한 Abstract이 있어 + +Control Abstract (제어추상화) + +Procedural Abstract (절차추상화) + +지금하려는건 ? Data Abstract (데이터 추상화) + + +ADT라는건 , 그냥 자료구조 자체를 의미해 + +애초에 자료구조라는게 어떄? +그냥 갖다 쓰는거잖아 , 그 안에 구현 어떻게돼있는지 다 알고 쓰나?? + +Map, Tree , Stack ,Queue ,Vector , Set , List , Array + +등등 이런 자료구조 들은 어떄? 전부다 data를 다루는 방식이야 + +data를 어떤식으로 다룰지 , 정렬을 자동으로 할건지 , 중복을 허용하는지 +등등의 data를 다루는 방식을 나타내는게 = ADT야 + +그리고 이 ADT를 구현하잖아? 그럼 그게 Data Structure, 자료구조임 + +대표적인 예시로 Stack , Queue 있는데 +FILO , FIFO 이라 유명한거일 뿐 + +Abstract Data Type은 엄청 많아. +애초에 모든 자료구조는 ADT를 구체화 한 것 뿐임 + +그냥 상황에 따라서 , 문제에 따라서 특정한 자료구조를 쓰는거야 + +예를들어 key값을 가지고 search하고싶어 그럼 map쓰는거야 + +인자를 계속해서 받고싶어 그래서 list 를 고려중이야 + +근데 중간중간에 삽입 삭제가 많을 것 같아 그럼 LinkedList + +아냐 삽입이 일어나도 맨 마지막에서만 일어나고 중간중간 삽입 삭제하는 과정이 +거의 없을 것 같아 , 그럼 ArrayList야 + +그냥 ADT는 말 그대로 내가 다루고싶은 data를 간략하게 만든거야 +자료구조일 뿐임 + +내가 쓸 용도에 맞는 자료구조를 쓰면 되는 거임 + + +우리가 재귀적으로 함수를 계속 부르면 나오는 에러가있어 + +그게뭐야? StackOverFLowError +서브루틴이 재귀적으로 실행되면 혹은 그냥 실행된다고 하더라도 + +이 모든 작업은 stack에 쌓인다. +모든 local 변수들 , 메서드의 파라미터 , return값 등등은 +stack에 쌓여 + +또 stack에는 size가 정해져 있는 것들만 올 수 있어 +그래서 size정해놓기 떄문에 overFlow라는 개념도 있는 것임 + +서브루틴이 활성화 되면 그 서브루틴에 대한 +Activation Records가 생성됨 +여기에는 local 변수 , parameter , 복귀주소 등이 포함돼있어 + + + +Binary Trees + +비선형구조에 대표적인 예시야 +그게 뭐야? Tree 자료구조 + +우리가 알고있는 대부분 stack , queue , list , deque , array +전부다 뭐야? Linear Structure야 + +즉 선형적으로 데이터를 저장해 + +근데 tree , graph는 비선형적으로 데이터 저장해 + +이진트리는 맨위에 root 가 있고 + +그 왼쪽 오른쪽 자식노드를 갖는 구조임 + +맨 아래에 있는 , 자식없는 노드를 leaf 노드라함 + + +얘는 순회할떄 3가지 있어 preOrder , inOrder ,postOrder + +전위 중위 후위인데 + +print -> left-> right 로 가면 전위순회 + +left-> print -> right 가면 중위 + +left -> right -> 해당노드 print 면 후위임 + +재귀적으로 불려져 + + + + +Binary Sort Trees + +이진 정렬트리를 이용하면 검색과 삽입이 모두 효과적이야 + + +Expression Trees + +표현식트리는 수학식을 간단하게 표현 가능해 + +얘는 postOrder로 식 계산이 가능해 + + +A Simple Recursive Descent Parser + +컴퓨터는 고급언어를 기계어로 번역해서 알아먹잖아 + +그걸 컴파일이라고 하고 , 그럼 컴파일을 어캐하는거지?? + + +Backus-Naur Form +(베커스 나우어 형식 , 베커스씨랑 나우어씨가 만든거) +컴퓨터 언어에서 언어의 문법을 수학적인 수식으로 나타낼 때 사용함 + + +자연어(인간이쓰는 말)과 인공언어(기계어)는 문법이나 구조를 가지고 있어 +따라서 일련의 규칙으로 표현이 가능해 + +이런 규칙의 표현을 BNF로 표현하기도 해 + +BNF는 생성 규칙들의 집합이야 , 예를 들면 + + → 0 | 1 | 2 | … | 9 + +이렇게 되면 digit은 0~9사이의 숫자가 되는 것 + +이 digit으로 이루어지면 숫자다 라고 정의내릴수 있게됨 + +또 다른 예시로 + + ::= + +::= 는 될수있다 를 의미 함 +이건 is가 아니라 can be임 , 왜?? 다른 것도 문장이 될 수도있잖아 + +즉 문장을 정의하는 또 다른 규칙이 있을수도 있어 + + + ::= | + ( ) + +동사구 can be 자동사 | (타동사 , 명사구) + + + ::= [ "that" ] | + [ ]... + + +명사구 can be 공통명사 [ 동사구 ] | 공통명사 | 전치사구 ] + +명사구는 공통명사 일 수도있고 , 뒤에 that 과 verb가 올 수도 있고 , 뒤에 전치사구가 올 수도 있습니다. + +또 얘네는 재귀적일 수 있어 명사구는 동사구로 부분적으로 정의되고 +동사구는 명사구로 부분적으로 정의 됨 + +이게 재귀적인거지 + +< 명사구> 는 <동사구> 로 부분적으로 정의되는 반면, <동사구> 는 <명사구> 로 부분적으로 정의됩니다 . +<명사구>는 "치즈를 먹은 쥐"가 될 수 있습니다. "치즈를 먹었다"는 < 동사구> 이기 때문입니다 . +그러나 그러면 우리는 재귀적으로 < 일반 명사> " the cat", 단어 "that" 및 <동사> 에서 더 복잡한 <명사구> +"the cat that catch the rat that ate the Cheese"를 만들 수 있습니다. -phrase> "치즈를 먹은 쥐를 잡았습니다". +거기에서 우리는 <명사구> "치즈를 먹은 쥐를 잡은 고양이를 쫓은 개"를 만들 수 있습니다 . + + +BNF는 Java와 같은 프로그래밍 언어의 구문을 형식적이고 정확한 방식으로 설명하는 데 사용될 수 있습니다. 예를 들어, 은 다음과 같이 정의될 수 있습니다. + + + ::= "while" "(" ")" + + +while - loop can be while(조건문) <실행문> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git "a/src/main/java/org/nhnacademy/lsj/\354\261\225\355\204\2609\355\200\264\354\246\210.txt" "b/src/main/java/org/nhnacademy/lsj/\354\261\225\355\204\2609\355\200\264\354\246\210.txt" new file mode 100644 index 0000000..2fd8e57 --- /dev/null +++ "b/src/main/java/org/nhnacademy/lsj/\354\261\225\355\204\2609\355\200\264\354\246\210.txt" @@ -0,0 +1,293 @@ +Question 1: + +Explain what is meant by a recursive subroutine. + +재귀서브루틴은 서브루틴이 자기 자신을 호출하는 것을 의미합니다. + + + +Question 2: + +Consider the following subroutine: + +static void printStuff(int level) { + if (level == 0) { + System.out.print("*"); + } + else { + System.out.print("["); + printStuff(level - 1); + System.out.print(","); + printStuff(level - 1); + System.out.print("]"); + } +} +Show the output that would be produced by the subroutine calls +printStuff(0), printStuff(1), printStuff(2), and printStuff(3). + + +* +[*,*] +[[*,*],[*,*]] +[[[*,*],[*,*]],[[*,*],[*,*]]] + + + +Question 3: + +Suppose that a linked list is formed from objects that belong to the class + +class ListNode { + int item; // An item in the list. + ListNode next; // Pointer to next item in the list. +} +Write a subroutine that will count the number of zeros that occur in a given linked list of ints. +The subroutine should have a parameter of type ListNode and should return a value of type int. + +ListNode 타입 변수 list가 있다면 + +int count=0; +while(list!=null){ + if(list.item==0) + count++; + list=list.next; +} + + + + +Question 4: + +Let ListNode be defined as in the previous problem. +Suppose that head is a variable of type ListNode that points to the first node in a linked list. +Write a code segment that will add the number 42 +in a new node at the end of the list. Assume that the list is not empty. +(There is no "tail pointer" for the list.) + + +ListNode p= head; + +while(p->next!=NULL){ + p=p->next; +} + +// p->next는 이제 null , 즉 끝 + +ListNode q=new ListNode(42); + +p->next=q; + + + +Question 5: + +List nodes can be used to build linked data structures that do not have the form of linked lists. Consider the list node class shown on the left and the code shown on the right: + +class ListNode { ListNode one = new ListNode(10); + int item; ListNode two = new ListNode(20); + ListNode next; ListNode three = new ListNode(30); + Listnode(int i) { ListNode four = new ListNode(40); + item = i; one.next = two; + next = null; two.next = three; + } three.next = four; +} four.next = two; +Draw the data structure that is constructed by the code. What happens if you try to print the items in the data structure using the usual code for traversing a linked list: + +ListNode runner = one; +while (runner != null) { + System.out.println(runner.item); + runner = runner.next(); +} + +10,20,30,40 (여기서부터 무한루프)20,30,40 + + +Question 6: + +What are the three operations on a stack? + +push , pop , isEmpty + + + +Question 7: + +What is the basic difference between a stack and a queue? + +구조가 다름 , stack은 선입후출 , queue는 선입선출 + + + +Question 8: + +What is an activation record? What role does a stack of activation records play in a computer? + +Activation Record는 서브루틴이 실행될떄 local 변수 , parameter , 복귀 메모리 등등을 +갖고있어 + +얘는 stack으로 구현이 돼있어 , 근데 왜 stack이냐? + +만약 다음과 같은 함수 있다고 치자 add(int i ,int j) return i+j; + +그럼 서브루틴이 만들어 지겟지? + +맨 처음에 int i push되고 , int j push , i+j push 될꺼야 + +그럼 결과값 반환해주려면 맨 위에있는 값만 pop해주면 되네? + +그래서 stack구조를 사용하는거임 + +모든 서브루틴은 Activation Records의 stack에 쌓이는거야 + + + + +Question 9: + +Suppose that a binary tree of integers is formed from objects belonging to the class + +class TreeNode { + int item; // One item in the tree. + TreeNode left; // Pointer to the left subtree. + TreeNode right; // Pointer to the right subtree. +} +Write a recursive subroutine that will find the sum of all the nodes in the tree. +Your subroutine should have a parameter of type TreeNode, +and it should return a value of type int. + + + +TreeNode tree; + +int sum=0; + +static int sum(TreeNode tree){ + int total=tree.item; + + if(tree->left!=null) + total+=sum(tree->left); + if(tree->right!=null) + total+=sum(tree->right); + + return total; + +} + + + +Question 10: + +Let TreeNode be the same class as in the previous problem. +Write a recursive subroutine that makes a copy of a binary tree. + The subroutine has a parameter that points to the root of the tree that is to be copied +. The return type is TreeNode, and the return value should be a pointer to the root of the copy. +The copy should consist of newly created nodes, +and it should have exactly the same structure as the original tree. + + + +static TreeNode copy(TreeNode tree){ + + TreeNode result; + + result = tree; + + if(tree->left!=null){ + result->left=tree->left; + copy(tree->left); + } + + if(tree->right!=null){ + result->right=tree->right; + copy(tree->right); + } + return result; + +} + + + +Question 11: + +What is a postorder traversal of a binary tree? + +후위순회란 + +left-> right ->print 순을 의미함 + +left로 갈 수 있을떄 까지 가 -> right로 갈 수 있을떄 까지 가 -> left , right 둘다 없거나 방문했으면 +그떄 print해 + +즉 자식노드를 모두 확인한 후에 부모노드를 확인하는 방법임 + + + + + + +Question 12: + +Suppose that a binary sort tree of integers is initially empty +and that the following integers are inserted into the tree in the order shown: + +5 7 1 3 4 2 6 +Draw the binary sort tree that results. Then list the integers in the order +that is produced by a post-order traversal of the tree. + + +2 4 3 1 6 7 5 + + 5 + 1 7 + 3 6 + 2 4 + + +Question 13: + +Suppose that a is defined by the BNF rule + + ::= | "(" [ ]... ")" +where a can be any sequence of letters. Give five different 's +that can be generated by this rule. (This rule, by the way, +is almost the entire syntax of the programming language LISP! +LISP is known for its simple syntax and its elegant and powerful semantics.) + + +tree , stack , heap , node , next + + +Question 14: + +Explain what is meant by parsing a computer program. + +Parsing = 구문분석 + +문장을 이루고있는 구성 성분으로 분해하고 관계를 분석하여 문장의 구조를 결정하는 것 + +컴퓨터 과학에서 parsing은 일련의 문자열을 의미있는 token으로 분해하고 그것들로 이루어진 + +Parse tree를 만드는 과정 + +Ex) 프로그램을 컴파일하는 과정에서 특정 프로그래밍 언어가 제시하는 문법을 잘 지켜서 작성했는지 검사하는 것 + +이 Parse tree를 만드는데 BNF같은 문법규칙을 사용한다. + + + + + + + + + + + + + + + + + + +