ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 4주차 과제: 제어문
    Programming/Java live study 2020. 12. 24. 02:11
     

    4주차 과제: 제어문 · Issue #4 · whiteship/live-study

    목표 자바가 제공하는 제어문을 학습하세요. 학습할 것 (필수) 선택문 반복문 과제 (옵션) 과제 0. JUnit 5 학습하세요. 인텔리J, 이클립스, VS Code에서 JUnit 5로 테스트 코드 작성하는 방법에 익숙해

    github.com

    목표

    자바가 제공하는 제어문을 학습하세요.

    학습할 것

     - 선택문

     - 반복문

     - 과제 0. JUnit 5 학습하세요.

     - 과제 1. live-study 대시 보드를 만드는 코드를 작성하세요.

     - 과제 2. LinkedList를 구현하세요.

     - 과제 3. Stack을 구현하세요.

     - 과제 4. 앞서 만든 ListNode를 사용해서 Stack을 구현하세요.

     - (optional) 과제 5. Queue를 구현하세요.


    제어문 이란?

    참고 :

    raccoonjy.tistory.com/10

    kils-log-of-develop.tistory.com/349

     

     Java의 인터프리터는 위에서 아래로, 오른쪽에서 왼쪽으로 코드를 해석한다. 그런 흐름을 변경할 수 있는 것이 제어문이다.

    1. 선택문

    1.1 if

     if 문은 3가지의 형태로 작성할 수 있다.

     

    public class Exam01 {
    
        public static void main(String[] args) {
            boolean condition = true; // 조건
    
            if (condition) { // 1
                System.out.println("조건이 true 입니다");
            }
    
            if (condition) System.out.println("조건이 true 입니다."); // 2
    
            if (condition) // 3
                System.out.println("조건이 true 입니다.");
        }
    }

     

    조건이 true 입니다
    조건이 true 입니다.
    조건이 true 입니다.

     

     모두 같은 문장을 출력한다. 실행되는 코드가 한줄인 경우 괄호 생략이 가능하고 또한 한줄로 생성이 가능하다.

    1.2 if-else

     else의 경우, if문의 조건이 false이면 실행되는 코드를 적는 공간이다. if와 마찬가지로 실행되는 코드가 한 줄인 경우 생략이 가능하다.

     

    public class Exam02 {
    
        public static void main(String[] args) {
            boolean condition = false; // 조건
    
            if (condition) {
                System.out.println("조건이 true 입니다.");
            } else {
                System.out.println("조건이 false 입니다.");
            }
    
            if (condition) System.out.println("조건이 true 입니다.");
            else System.out.println("조건이 false 입니다.");
    
            if (condition)
                System.out.println("조건이 true 입니다.");
            else
                System.out.println("조건이 false 입니다.");
        }
    }

     

     

    조건이 false 입니다.
    조건이 false 입니다.
    조건이 false 입니다.

    1.3 if-else if

     다양한 조건을 가진 경우 if 문을 묶어서 여러번 사용할 수 있다. 위에서 부터 조건문을 실행하고 true이면 해당하는 코드를 실행하고 전체 조건문을 벗어난다. 그렇기 때문에 조건문에 배치 순서에 유의하여 작성해야 한다.

     

    public class Exam03 {
    
        public static void main(String[] args) {
            int score = 97;
    
            if (score >= 90) {
                System.out.println("A");
            } else if (score >= 80) {
                System.out.println("B");
            } else if (score >= 70) {
                System.out.println("C");
            } else if (score >= 60) {
                System.out.println("D");
            } else {
                System.out.println("F");
            }
    
            if (score >= 90) System.out.println("A");
            else if (score >= 80) System.out.println("B");
            else if (score >= 70) System.out.println("C");
            else if (score >= 60) System.out.println("D");
            else System.out.println("F");
    
            if (score >= 90)
                System.out.println("A");
            else if (score >= 80)
                System.out.println("B");
            else if (score >= 70)
                System.out.println("C");
            else if (score >= 60)
                System.out.println("D");
            else
                System.out.println("F");
        }
    }

     

     

    A
    A
    A

    1.4 중첩된 if 

    public class Exam04 {
    
        public static void main(String[] args) {
            int score = 97;
    
            if (score >= 50) {
                System.out.println("평균 이상입니다.");
                if (score >= 90) {
                    System.out.println("A 학점이 보장됩니다.");
                } else {
                    System.out.println("A 학점을 보장할 수 없습니다.");
                }
            } else {
                System.out.println("평균 이하입니다.");
            }
        }
    }

     

    평균 이상입니다.
    A 학점이 보장됩니다.

     

     if 문 안에 if 문을 얼마든지 중첩하여 사용할 수 있다. 하지만 과도한 사용은 가독성을 떨어트릴 수 있다.

    1.5 switch

    switch문 표현식은 byte, short, int, long, enum, String 및 Byte, Short, Int, Long과 같은 Wrapper 클래스가 들어갈 수 있다. 단 Wrapper 클래스는 표현식에만 허용하고, case에서는 허용하지 않는다. 또한 floatdouble의 경우 정밀도로 동일하게 보일 때 정확하지 않을 수 있기 때문에 허용하지 않는다.

     

    public class Exam05 {
    
        public static void main(String[] args) {
            int score = 97;
    
            switch (score / 10) {
                case 9:
                    System.out.println("A");
                    break;
                case 8:
                    System.out.println("B");
                    break;
                case 7:
                    System.out.println("C");
                    break;
                case 6:
                    System.out.println("D");
                    break;
                default:
                    System.out.println("F");
            }
        }
    }
    

     

    A

     

     

      위에서 부터 수식에 결과 값을 case마다 비교한다. 일치하면 해당 case에 코드를 실행한다. break가 있다면 조건문을 벗어난다. 하지만 break가 없다면 밑에 case와 또다시 비교한다.

     

    public class Exam05 {
    
        public static void main(String[] args) {
            score = 90;
    
            switch (score / 10) {
                case 9:
                    System.out.println("A");
                case 8:
                    System.out.println("B");
                case 7:
                    System.out.println("C");
                case 6:
                    System.out.println("D");
                default:
                    System.out.println("F");
            }
        }
    }

     

    A
    B
    C
    D
    F

     

     break에 도달할 때 까지 다음 case를 계속 실행하게 되고, default를 만나서 switch 조건문을 탈출하게 된다. 이것을 풀 스루 (fall-through) 라고 한다.

     

     이러한 점을 의도하여 사용할 수도 있다.

     

    public class Exam06 {
    
        public static void main(String[] args) {
            int score = 97;
    
            switch (score) {
                case 100:
                case 99:
                case 98:
                case 97:
                case 96:
                case 95:
                    System.out.println("A+");
                    break;
                default:
                    System.out.println("A");
            }
        }
    }

    2. 반복문

    2.1 while

    해당 조건이 만족할 때 까지 코드를 반복하여 실행한다. 반복 횟수가 고정되지 않은 경우 while 루프를 사용하는 것이 좋다.

     

    public class Exam07 {
    
        public static void main(String[] args) {
            int index = 0;
    
            while (index != 10) {
                System.out.println(index);
                ++index;
            }
        }
    }

     

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9

     

     

      조건이 true이면 해당 loop를 계속 반복한다. loop를 실행하던 도중 break를 만나거나 조건이 false가 되면 즉시 loop를 탈출한다. loop를 멈출 수 있는 flag가 없다면 무한루프에 빠질 수 있다.

     

    public class Exam08 {
    
        public static void main(String[] args) {
            int index = 0;
    
            while (true) {
                System.out.println(index);
                ++index;
    
                if (index == 10) break; // while 탈출을 위한 flag
            }
        }
    }

     

     위 코드는 조건에 true를 넣었기 때문에 무한으로 루프를 돈다. 하지만 index == 10 일 때 break를 만나 while 문을 탈출한다. 

     

    2.2 do-while

    public class Exam09 {
    
        public static void main(String[] args) {
            int index = 0;
    
            do {
                System.out.println(index);
                ++index;
    
            } while (index != 10);
        }
    }

     

      일반적인 while문과 상당부분 유사하지만 do-while문은 적어도 한번의 loop를 실행한다. 초기 조건을 비교하기 전에 처리해야 될 코드가 있을 때 혹은 무조건 한번 이상 실행시켜야 할 경우 유용하게 사용된다.

    2.3 for

    public class Exam10 {
    
        public static void main(String[] args) {
    
            for (int i = 0; i < 10; i++) {
                System.out.println(i);
            }
        }
    }

     

     초기의 값을 선언하여 해당 값이 조건에 충족되는 동안 loop를 반복한다. for은 loop의 횟수가 정해져 있을 때 유용하게 사용될 수 있다.

     

     for문은 for ( 1; 2; 3) 이러한 형태와 코드가 있는 바디 부분이 있다.

     

     1. 초기화를 진행하는 공간이다. 변수를 초기화할 때 주로 사용된다. 루프를 시작하면 한 번만 실행되는 공간이다.

     2. 조건이 들어간다. 반환값이 true, false 즉 boolean 값 이어야 한다. 해당 조건은 루프를 한 번 돌 때 마다 실행된다.

     3. 증가 및 감소 연산이다. 초기화 구문에서 생성한 변수의 index 값을 증가시키거나 감소시킨다.

     

    for 문이 실행되는 과정

     

    for (;;;) {
    }

     for문으로 무한 루프를 만들기 위해선 위 처럼 작성하면 된다.

    2.4 for each

      for each는 java 5 부터 추가되었다. for each라는 키워드가 있는것은 아니다. 기존 for문을 살짝 수정하면 바로 적용할 수 있다.

     

    public class Exam11 {
    
        public static void main(String[] args) {
            String[] seasons = {"봄", "여름", "가을", "겨울"};
    
            for (String season : seasons) {
                System.out.println(season);
            }
        }
    }

     

      iterate 객체에서 하나씩 순차적으로 값에 대입되어 loop를 수행한다. list나 map등의 모든 항목들을 탐색할 때 매우 직관적이고 유용하게 사용할 수 있다. 하지만 기존의 for문 자체에서 횟수를 제어할 수는 없다.


    기타 제어문

      제어문, 즉 선택문과 반복문은 중첩하여 사용할 수 있다. 중첩된 제어문들을 탈출하거나 지속하기 위해서는 break와 continue가 필요하다.

    • break : 반복문을 즉시 탈출한다.
    • continue : 반복문의 이하 코드를 실행하지 않고 다음 loop로 건너뛴다.
    public class Exam12 {
    
        public static void main(String[] args) {
    
            int sum = 0;
    
            for (int i = 0; i < 10; i++) {
                if (i == 0) {
                    sum = 100;
                    continue;
                }
    
                sum += i;
            }
    
            System.out.println(sum); // 145
        }
    }

     

    public class Exam12 {
    
        public static void main(String[] args) {
    
            int sum = 0;
    
            for (int i = 0; i < 10; i++) {
                if (i == 0) {
                    sum = 100;
                    break;
                }
    
                sum += i;
            }
    
            System.out.println(sum); // 100
        }
    }
    

     

     continue를 만나게 되면 밑의 코드는 무시하고 loop를 진행한다. break는 그 즉시 loop를 중단하고 벗어난다.


    [더 알아보기] java에서 이중루프를 빠져나가고 싶다면?

      일반적인 break는 하나의 loop만을 빠져나갈 수 있다. 중첩된 loop를 빠져나가고 싶다면 for문 위에 label를 명시해 두면 된다. 해당 label이 명시된 break를 만난다면 중첩된 반복문을 모두 빠져나온다.

     

    public class Exam13 {
    
        public static void main(String[] args) {
    
            int num = 15;
    
            loop:
            for (int i = 0; i < 10; i++) {
                for (int j = 0; j < 10; j++) {
                    if (i * j == num) {
                        System.out.println("이중 for 문 탈출");
                        break loop;
                    }
                    System.out.println(i + ", " + j);
                }
            }
        }
    }

     

     i * j == 15인 시점에 이중 루프를 벗어난다.


    과제 0. JUnit 5 학습하세요.

    ※ JUnit4에 대하여 잘 알지 못하기 때문에 JUnit5 위주로 작성하였다. ※

      Spring Boot 2.2.x는 JUnit4가 아닌 JUnit5를 기본으로 제공한다. JUnit5 Java Test framework는 3가지의 컴포넌트로 구성되어 있다.

    • JUnit Platform: JUnit Platform은 JVM에서 테스트 프레임워크를 시작하기 위한 기초적인 역할을 수행한다. 추가적으로 테스트 개발을 위한 API를 제공한다.

    • JUnit Jupiter: JUnit5에서 테스트 및 Extension을 작성하기 위한 TestEngine을 제공한다.

    • JUnit Vintage: 하위 호환성을 위한 TestEngine이다. JUnit4, JUnit3를 실행할 수 있다.

      JUnit5를 사용하기 위해서는 JDK 8 버전 이상을 사용해야 한다.

    life cycle

      Junit5에는 다양한 어노테이션을 활용하여 life cycle를 사용한다.

    • @BeforeAll: 모든 테스트 실행 전 최초에 한번 실행한다.
    • @BeforeEach: 각각의 테스트를 실행하기 전에 실행한다.
    • @Test: 테스트를 실행한다.
    • @AfterEach: 각각의 테스트를 종료한 후 실행한다.
    • @AfterAll: 모든 테스트 종류 후 마지막에 실행한다.
    • @Disabled: 테스트를 수행하지 않는다.
    • @DisplayName: 테스트의 이름을 설정한다.

    표준 테스트 클래스

     

    class StandardTests {
    
        @BeforeAll
        static void initAll() {
        }
    
        @BeforeEach
        void init() {
        }
    
        @Test
        void succeedingTest() {
        }
    
        @Test
        void failingTest() {
            fail("a failing test");
        }
    
        @Test
        @Disabled("for demonstration purposes")
        void skippedTest() {
            // not executed
        }
    
        @Test
        void abortedTest() {
            assumeTrue("abc".contains("Z"));
            fail("test should have been aborted");
        }
    
        @AfterEach
        void tearDown() {
        }
    
        @AfterAll
        static void tearDownAll() {
        }
    
    } 

     

    참고 :

     

    JUnit 5 User Guide

    Although the JUnit Jupiter programming model and extension model will not support JUnit 4 features such as Rules and Runners natively, it is not expected that source code maintainers will need to update all of their existing tests, test extensions, and cus

    junit.org

     

    displayName

     

    @DisplayName("A special test case")
    class DisplayNameDemo {
    
        @Test
        @DisplayName("Custom test name containing spaces")
        void testWithDisplayNameContainingSpaces() {
        }
    
        @Test
        @DisplayName("╯°□°)╯")
        void testWithDisplayNameContainingSpecialCharacters() {
        }
    
        @Test
        @DisplayName("😱")
        void testWithDisplayNameContainingEmoji() {
        }
    
    }

     

      @displayName은 문자열 뿐만아니라 공백, 특수 문자, 이모지 등을 사용하여 선언할 수 있다.

     

    참고 : 

     

    JUnit 5 User Guide

    Although the JUnit Jupiter programming model and extension model will not support JUnit 4 features such as Rules and Runners natively, it is not expected that source code maintainers will need to update all of their existing tests, test extensions, and cus

    junit.org

    Assertions

      JUnit4가 가지고 있는 많은 assertion 메소드와 함께 제공되고, Java 8 람다식과 함께 사용하기에 적합한 몇 가지가 추가되었다. 모든 JUnit Jupiter Assertions 클래스는 static 메소드이다.

     

    class AssertionsDemo {
    
        private final Calculator calculator = new Calculator();
    
        private final Person person = new Person("Jane", "Doe");
    
        @Test
        void standardAssertions() {
            assertEquals(2, calculator.add(1, 1));
            assertEquals(4, calculator.multiply(2, 2),
                    "The optional failure message is now the last parameter");
            assertTrue('a' < 'b', () -> "Assertion messages can be lazily evaluated -- "
                    + "to avoid constructing complex messages unnecessarily.");
        }
    
        @Test
        void groupedAssertions() {
            // In a grouped assertion all assertions are executed, and all
            // failures will be reported together.
            assertAll("person",
                () -> assertEquals("Jane", person.getFirstName()),
                () -> assertEquals("Doe", person.getLastName())
            );
        }
    
        @Test
        void dependentAssertions() {
            // Within a code block, if an assertion fails the
            // subsequent code in the same block will be skipped.
            assertAll("properties",
                () -> {
                    String firstName = person.getFirstName();
                    assertNotNull(firstName);
    
                    // Executed only if the previous assertion is valid.
                    assertAll("first name",
                        () -> assertTrue(firstName.startsWith("J")),
                        () -> assertTrue(firstName.endsWith("e"))
                    );
                },
                () -> {
                    // Grouped assertion, so processed independently
                    // of results of first name assertions.
                    String lastName = person.getLastName();
                    assertNotNull(lastName);
    
                    // Executed only if the previous assertion is valid.
                    assertAll("last name",
                        () -> assertTrue(lastName.startsWith("D")),
                        () -> assertTrue(lastName.endsWith("e"))
                    );
                }
            );
        }
    
        @Test
        void exceptionTesting() {
            Exception exception = assertThrows(ArithmeticException.class, () ->
                calculator.divide(1, 0));
            assertEquals("/ by zero", exception.getMessage());
        }
    
        @Test
        void timeoutNotExceeded() {
            // The following assertion succeeds.
            assertTimeout(ofMinutes(2), () -> {
                // Perform task that takes less than 2 minutes.
            });
        }
    
        @Test
        void timeoutNotExceededWithResult() {
            // The following assertion succeeds, and returns the supplied object.
            String actualResult = assertTimeout(ofMinutes(2), () -> {
                return "a result";
            });
            assertEquals("a result", actualResult);
        }
    
        @Test
        void timeoutNotExceededWithMethod() {
            // The following assertion invokes a method reference and returns an object.
            String actualGreeting = assertTimeout(ofMinutes(2), AssertionsDemo::greeting);
            assertEquals("Hello, World!", actualGreeting);
        }
    
        @Test
        void timeoutExceeded() {
            // The following assertion fails with an error message similar to:
            // execution exceeded timeout of 10 ms by 91 ms
            assertTimeout(ofMillis(10), () -> {
                // Simulate task that takes more than 10 ms.
                Thread.sleep(100);
            });
        }
    
        @Test
        void timeoutExceededWithPreemptiveTermination() {
            // The following assertion fails with an error message similar to:
            // execution timed out after 10 ms
            assertTimeoutPreemptively(ofMillis(10), () -> {
                // Simulate task that takes more than 10 ms.
                new CountDownLatch(1).await();
            });
        }
    
        private static String greeting() {
            return "Hello, World!";
        }
    
    }

     

      좀 더 공부한 뒤 새로운 프로젝트에 적용하고 따로 게시글을 작성할 예정이다.

     

    참고 : https://junit.org/junit5/docs/current/user-guide/#overview-what-is-junit-5

     

    JUnit 5 User Guide

    Although the JUnit Jupiter programming model and extension model will not support JUnit 4 features such as Rules and Runners natively, it is not expected that source code maintainers will need to update all of their existing tests, test extensions, and cus

    junit.org


    과제 1. live-study 대시 보드를 만드는 코드를 작성하세요.

    • 깃헙 이슈 1번부터 18번까지 댓글을 순회하며 댓글을 남긴 사용자를 체크 할 것.
    • 참여율을 계산하세요. 총 18회에 중에 몇 %를 참여했는지 소숫점 두자리가지 보여줄 것.
    • Github 자바 라이브러리를 사용하면 편리합니다.
    • 깃헙 API를 익명으로 호출하는데 제한이 있기 때문에 본인의 깃헙 프로젝트에 이슈를 만들고 테스트를 하시면 더 자주 테스트할 수 있습니다.

     

    import org.kohsuke.github.*;
    
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    
    public class Homework01 {
    
        public static void main(String[] args) throws IOException {
    
            String myToken = "발급 받은 token";
            GitHub gitHub = new GitHubBuilder().withOAuthToken(myToken).build();
            GHRepository repository = gitHub.getRepository("hyeonic/live-study").getSource();
    
            Map<String, Integer> participantMap = new HashMap<String, Integer>();
    
            GHIssue issue;
            PagedIterable<GHIssueComment> comments;
            for (int i = 1; i < 19; i++) {
                issue = repository.getIssue(i);
                comments = issue.listComments();
                for (GHIssueComment comment : comments) {
                    String participant = comment.getUser().getName();
                    if (participant != null) {
                        if (participantMap.containsKey(participant)) {
                            participantMap.put(participant, participantMap.get(participant) + 1);
                        } else {
                            participantMap.put(participant, 1);
                        }
                    }
                }
            }
    
            for (String user : participantMap.keySet()) {
                System.out.println("참여자: " + user);
                System.out.printf("참여율: %.2f%% \n\n", ((float)participantMap.get(user) * 100 / 18));
            }
    
        }
    }

     


     

    과제 2. LinkedList를 구현하세요.

    • LinkedList에 대해 공부하세요.
    • 정수를 저장하는 ListNode 클래스를 구현하세요.
    • ListNode add(ListNode head, ListNode nodeToAdd, int position)를 구현하세요.
    • ListNode remove(ListNode head, int positionToRemove)를 구현하세요.
    • boolean contains(ListNode head, ListNode nodeTocheck)를 구현하세요.

     

    public class Homework02 {
    
        static class ListNode {
            private int value;
            private ListNode next;
    
            public ListNode(int value) {
                this.value = value;
                next = null;
            }
        }
    
        static class LinkedList {
            public ListNode add(ListNode head, ListNode nodeToAdd, int position) {
    
                ListNode tempNode = head;
    
                if (head == null) return nodeToAdd;
                if (position == 0) {
                    ListNode add = nodeToAdd;
                    nodeToAdd.next = tempNode;
                    return nodeToAdd;
                }
    
                for (int i = 0; i < position - 1; i++) {
                    tempNode = tempNode.next;
                }
    
                nodeToAdd.next = tempNode.next;
                tempNode.next = nodeToAdd;
    
                return head;
            }
    
            public ListNode remove(ListNode head, int positionToRemove) {
    
                ListNode tempNode = head;
    
                for (int i = 0; i < positionToRemove - 1; i++) {
                    tempNode = tempNode.next;
                }
    
                tempNode.next = tempNode.next.next;
    
                return head;
            }
    
            public boolean contains(ListNode head, ListNode nodeToCheck) {
    
                ListNode tempNode = head;
    
                while (tempNode != null) {
                    if (tempNode.value == nodeToCheck.value) {
                        return true;
                    }
                    tempNode = tempNode.next;
                }
    
                return false;
            }
    
            public void print(ListNode head) {
    
                ListNode tempNode= head;
    
                while (tempNode != null) {
                    System.out.print(tempNode.value + " -> ");
                    tempNode = tempNode.next;
                }
                System.out.println("null");
            }
        }
    
        public static void main(String[] args) {
    
            LinkedList numbers = new LinkedList();
            ListNode head = null;
    
            for (int i = 0; i < 10; i++) {
                head = numbers.add(head, new ListNode(i), i);
            }
    
            System.out.println("contain 1? " + numbers.contains(head, new ListNode(1)));
            System.out.println("contain 2? " + numbers.contains(head, new ListNode(2)));
    
            numbers.print(head);
    
            System.out.println("remove index 1");
            System.out.println("remove index 1");
            numbers.remove(head, 1);
            numbers.remove(head, 1);
    
            System.out.println("contain 1? " + numbers.contains(head, new ListNode(1)));
            System.out.println("contain 2? " + numbers.contains(head, new ListNode(2)));
    
            numbers.print(head);
    
        }
    
    }
    

     

     


    과제 3. Stack을 구현하세요.

    • int 배열을 사용해서 정수를 저장하는 Stack을 구현하세요.
    • void push(int data)를 구현하세요.
    • int pop()을 구현하세요.

     

    public class Homework03 {
    
        static class Stack {
            private int[] stack;
            private int size;
            private int index;
    
            public Stack(int size) {
                stack = new int[size];
                this.size = size;
                index = 0;
            }
    
            public void push(int data) {
                if (indexValidation(index, "push")) {
                    stack[index] = data;
                    ++index;
                } else {
                    System.out.println("stack이 가득 찼습니다.");
                }
            }
    
            public int pop() {
                if (indexValidation(index, "pop")) {
                    int result = stack[index - 1];
                    stack[index - 1] = 0;
                    --index;
                    return result;
                } else {
                    System.out.println("stack이 비어있습니다.");
                    return 0;
                }
            }
    
            public void print() {
                for (int i = size - 1; i >= 0; i--) {
                    System.out.println(i + " : " + stack[i]);
                }
            }
    
            private boolean indexValidation(int index, String method) {
                if (index == this.size - 1 && method.equals("push")) {
                    return false;
                } else if (index == 0 && method.equals("pop")) {
                    return false;
                }
    
                return true;
            }
        }
    
        public static void main(String[] args) {
            int size = 7;
            Stack arrStack = new Stack(size);
            arrStack.push(1);
            arrStack.push(2);
            arrStack.push(3);
            arrStack.print();
    
            System.out.println();
    
            arrStack.push(4);
            arrStack.push(5);
            arrStack.print();
    
            System.out.println();
    
            System.out.println("pop : " + arrStack.pop());
            System.out.println("pop : " + arrStack.pop());
            arrStack.print();
        }
    } 

     

     

     


    과제 4. 앞서 만든 ListNode를 사용해서 Stack을 구현하세요.

    • ListNode head를 가지고 있는 ListNodeStack 클래스를 구현하세요.
    • void push(int data)를 구현하세요.
    • int pop()을 구현하세요.

     

    public class Homework04 {
    
        static class ListNode {
    
            private int value;
            private ListNode next;
    
            public ListNode(int value) {
                this.value = value;
                next = null;
            }
        }
    
        static class LinkedStack {
            ListNode head;
    
            public LinkedStack() {
                head = null;
            }
    
            public void push(int data) {
    
                ListNode temp = head;
                ListNode addNode = new ListNode(data);
    
                if (temp == null) {
                    head = addNode;
                    return;
                }
    
                while (temp.next != null) {
                    temp = temp.next;
                }
    
                temp.next = addNode;
            }
    
            public int pop() {
    
                ListNode temp = head;
    
                while (temp.next.next != null) {
                    temp = temp.next;
                }
    
                ListNode result = temp.next;
                temp.next = null;
    
                return result.value;
            }
    
            public void print() {
    
                ListNode tempNode = head;
    
                while (tempNode != null) {
                    System.out.print(tempNode.value + " -> ");
                    tempNode = tempNode.next;
                }
                System.out.println("null");
            }
        }
    
        public static void main(String[] args) {
            LinkedStack numbers = new LinkedStack();
    
            for (int i = 0; i < 10; i++) {
                numbers.push(i);
            }
    
            numbers.print();
            System.out.println("pop 1 " + numbers.pop());
            System.out.println("pop 2 " + numbers.pop());
    
            numbers.print();
        }
    }

     

     


    과제 5. Queue를 구현하세요.

    • 배열을 사용해서 한번
    • ListNode를 사용해서 한번.

     

    public class Homework05 {
    
        public static class ArrayQueue {
            private int[] queue;
            private int size;
            private int index;
    
            public ArrayQueue(int size) {
                queue = new int[size];
                this.size = size;
                index = 0;
            }
    
            public void push(int data) {
                if (indexValidation(index, "push")) {
                    queue[index] = data;
                    ++index;
                } else {
                    System.out.println("queue가 가득 찼습니다.");
                }
            }
    
            public int peek() {
                if (indexValidation(index, "peek")) {
                    int result = queue[0];
                    for (int i = 1; i < size; i++) {
                        queue[i - 1] = queue[i];
                    }
                    queue[index] = 0;
                    --index;
                    return result;
                } else {
                    System.out.println("queue가 비어있습니다.");
                    return 0;
                }
            }
    
            private boolean indexValidation(int index, String method) {
                if (index == this.size - 1 && method.equals("push")) {
                    return false;
                } else if (index == 0 && method.equals("peek")) {
                    return false;
                }
    
                return true;
            }
    
        }
    
        public static class ListNode {
    
            private int value;
            private ListNode next;
    
            public ListNode(int value) {
                this.value = value;
                next = null;
            }
        }
    
        public static class LinkedQueue {
            ListNode head;
    
            public LinkedQueue() {
                head = null;
            }
    
            public void push(int data) {
                ListNode temp = head;
                ListNode addNode = new ListNode(data);
    
                if (temp == null) {
                    head = addNode;
                    return;
                }
    
                while (temp.next != null) {
                    temp = temp.next;
                }
    
                temp.next = addNode;
            }
    
            public int peek() {
    
                ListNode temp = head;
                ListNode result = temp;
                head = temp.next;
    
                return result.value;
            }
    
            public void print() {
    
                ListNode tempNode = head;
    
                while (tempNode != null) {
                    System.out.print(tempNode.value + " -> ");
                    tempNode = tempNode.next;
                }
                System.out.println("null");
            }
        }
    
    }

     

    import org.junit.Test;
    import org.junit.jupiter.api.DisplayName;
    
    import static org.junit.jupiter.api.Assertions.*;
    
    public class Homework05Test {
    
        @Test
        @DisplayName("array queue 에 5개의 data 를 추가하는 테스트")
        public void addArrayQueue() {
    
            // Given
            Homework05.ArrayQueue arrayQueue = new Homework05.ArrayQueue(10);
    
            // When
            for (int i = 0; i < 5; i++) {
                arrayQueue.push(i);
            }
    
            // Then
            assertEquals(0, arrayQueue.peek());
            assertEquals(1, arrayQueue.peek());
            assertEquals(2, arrayQueue.peek());
            assertEquals(3, arrayQueue.peek());
            assertEquals(4, arrayQueue.peek());
        }
    
        @Test
        @DisplayName("Linked queue 에 5개의 data 를 추가하는 테스트")
        public void addLinkedListQueue() {
    
            // Given
            Homework05.LinkedQueue linkedQueue = new Homework05.LinkedQueue();
    
            // When
            for (int i = 0; i < 5; i++) {
                linkedQueue.push(i);
            }
    
            // Than
            assertEquals(0, linkedQueue.peek());
            assertEquals(1, linkedQueue.peek());
            assertEquals(2, linkedQueue.peek());
            assertEquals(3, linkedQueue.peek());
            assertEquals(4, linkedQueue.peek());
        }
    }

     

    아쉬운 점

      학교 시험 기간과 병행하여 작성하다 보니 상당 부분 부족한 점이 많았다. 종강 이후 4주차까지 다시 한 번 복습하며 나의 지식으로 만들어야 겠다. 테스트 코드 관련 게시글과 과제에 대한 세부 사항을 만들어 게시할 예정이다.

    댓글

Designed by Tistory.