Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

수식 트리 구현 (4주차 끝) #31

Merged
merged 8 commits into from
Aug 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions yoonexample/src/main/java/tree/expressiontree/ExpressionTree.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package tree.expressiontree;

/**
* 수식 트리 인터페이스
*/
public interface ExpressionTree {

/**
* 트리의 값을 계산합니다.
*
* @return 트리를 가지고 연산한 값
*/
int evaluateTree();

/**
* 전위 표기법으로 표현합니다.
*
* @param sb 표기법이 저장될 공간
*/
void prefixTypeExpression(StringBuilder sb);

/**
* 중위 표기법으로 표현합니다.
*
* @param sb 표기법이 저장될 공간
*/
void infixTypeExpression(StringBuilder sb);

/**
* 후위 표기법으로 표현합니다.
*
* @param sb 표기법이 저장될 공간
*/
void postfixTypeExpression(StringBuilder sb);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package tree.expressiontree;

import stack.ListStack;
import stack.Stack;
import tree.binarytree.TraversableBinaryTreeNode;
import tree.binarytree.TraversableBinaryTreeNodeImpl;

public class ExpressionTreeImpl implements ExpressionTree {

private TraversableBinaryTreeNode<Character> root;

public ExpressionTreeImpl(char[] postfixExpression) {
Stack<TraversableBinaryTreeNode<Character>> stack = new ListStack<>();

for (char expr : postfixExpression) {
TraversableBinaryTreeNode<Character> node = new TraversableBinaryTreeNodeImpl<>(expr);
if (!Character.isDigit(expr)) { // 숫자가 아니라면, 연산자임
node.setRightSubTree(stack.pop());
node.setLeftSubTree(stack.pop());
}

stack.push(node);
}

this.root = stack.pop();
}

@Override
public int evaluateTree() {
return evaluateTree(this.root);
}

private int evaluateTree(TraversableBinaryTreeNode<Character> node) {
TraversableBinaryTreeNode<Character> leftSubTree = node.getLeftSubTree();
TraversableBinaryTreeNode<Character> rightSubTree = node.getRightSubTree();

if (leftSubTree == null && rightSubTree == null) {
return Character.getNumericValue(node.getData()); // 단말 노드는 피연산자임
}

int op1 = 0;
int op2 = 0;
if (leftSubTree != null) {
op1 = evaluateTree(leftSubTree);
}
if (rightSubTree != null) {
op2 = evaluateTree(rightSubTree);
}

switch (node.getData()) {
case '+':
return op1 + op2;
case '-':
return op1 - op2;
case '*':
return op1 * op2;
case '/':
if (op2 == 0) {
throw new ArithmeticException("Can't be division by zero.");
}
return op1 / op2;
}

return 0;
}

@Override
public void prefixTypeExpression(StringBuilder sb) {
this.root.preorderTraverse(sb);
}

@Override
public void infixTypeExpression(StringBuilder sb) {
this.root.inorderTraverse(sb);
}

@Override
public void postfixTypeExpression(StringBuilder sb) {
this.root.postorderTraverse(sb);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package tree.expressiontree;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import stack.InfixToPostfix;

class ExpressionTreeTest {

InfixToPostfix infixToPostfix;

@BeforeEach
void setUp() {
infixToPostfix = new InfixToPostfix();
}

@Test
@DisplayName("수식_트리_테스트")
void 수식_트리_테스트() {
String infixExpression = "1 + 2";
char[] postfixExpression = infixToPostfix.convertInputToPostfix(infixExpression);

ExpressionTree expressionTree = new ExpressionTreeImpl(postfixExpression);
assertThat(expressionTree.evaluateTree()).isEqualTo(3);

StringBuilder sb = new StringBuilder();
expressionTree.prefixTypeExpression(sb);
assertThat(sb.toString()).isEqualTo("+12");

sb = new StringBuilder();
expressionTree.infixTypeExpression(sb);
assertThat(sb.toString()).isEqualTo("1+2");

sb = new StringBuilder();
expressionTree.postfixTypeExpression(sb);
assertThat(sb.toString()).isEqualTo("12+");
}

@Test
@DisplayName("수식_트리_테스트2")
void 수식_트리_테스트2() {
String infixExpression = "1 + 2 * 7";
char[] postfixExpression = infixToPostfix.convertInputToPostfix(infixExpression);

ExpressionTree expressionTree = new ExpressionTreeImpl(postfixExpression);
assertThat(expressionTree.evaluateTree()).isEqualTo(15);

StringBuilder sb = new StringBuilder();
expressionTree.prefixTypeExpression(sb);
assertThat(sb.toString()).isEqualTo("+1*27");

sb = new StringBuilder();
expressionTree.infixTypeExpression(sb);
assertThat(sb.toString()).isEqualTo("1+2*7");

sb = new StringBuilder();
expressionTree.postfixTypeExpression(sb);
assertThat(sb.toString()).isEqualTo("127*+");
}
}