카테고리 없음

잡동사니 팀: 모각코 1주차 1회모임 결과 (24.01.06 / 토요일 / 10시 ~ 13시)

용범 2024. 1. 6. 13:01
/*
 * Stack
 * LIFO : 마지막에 넣은 걸 먼저 꺼냄
 * push : 스택에 넣는 것
 * pop : 스택에서 꺼내는 것
 * 스택은 배열로 구현하는 것이 좋음 (순차적 추가, 순차적 삭제)
 * Stack이라는 클래스 존재
 *
 * 스택의 method
 * boolean empty() : Stack이 비어있는지 반환
 * Object peek() : Stack 맨 위에 저장된 객체 반환
 * Object pop() : Stack 맨 위에 저장된 객체를 꺼내면서 반환
 * Object push(Object item) : Stack에 item 저장
 * int search(Object o) : Stack에서 객체(o)를 찾아서 그 위치 반환, 없으면 -1 봔환 (배열은 0부터 시작하지만, 스택은 top부터 1로 시작)
 *
 *--------------------------------------------------------------------------------------------------------------------------
 *
 * Queue
 * FIFO : 먼저 넣은 걸 먼저 꺼냄
 * offer : 큐에 넣는 것
 * poll : 큐에서 꺼내는 것
 * 큐는 linked list로 구현하는 것이 좋음 (배열로 구현하면 자리 이동 필요)
 * Queue는 인터페이스로 정의되어있음
 * -> 객체 생성 불가
 * 1. Queue 직접 구현
 * 2. Queue 인터페이스를 구현한 클래스 사용해서 객체 생성 ex)AbstracQueue, ArrayDeque, LinkedList, PriorityQueue
 * -> Queue q = new LinkedList();와 같이 객체 생성
 * Queue 인터페이스에는 없는 메소드를 사용하는 것을 막기 위해 참조 변수의 타입을 조상(Queue 인터페이스)으로 좁히는게 좋음
 *
 * 큐의 method
 * boolean add(Object o) : 객체를 큐에 추가(성공하면 true, 저장공간 부족으로 실패하면 IllegalStateException 발생)
 * Object remove() : 큐에서 맨 앞(제일 먼저 들어온) 객체를 꺼내 반환 (큐가 비어있으면 NoSuchElementException 발생)
 * Object element() : 큐에서 맨 앞 객체 반환 (큐가 비어 있으면 NoSuchElementException 발생)
 * boolean offer(Object o) : 객체를 큐에 추가 (성공하면 true, 실패하면 false 반환)
 * Object poll() : 큐에서 맨 앞 객체를 꺼내서 반환 (비어있으면 null 반환)
 * Object peek() : 큐에서 맨 앞 객체 반환 (큐가 비어있으면 null 반환)
 *
 * 위에 3개는 예외 발생
 * 밑에 3개는 예외 발생x
 */

 

 

예시1

package week1;

import java.util.*;

public class StackQueue_Ex1 {
    public static void main(String[] args) {
        Stack st = new Stack();
        Queue q = new LinkedList();

        st.push(0);
        st.push(1);
        st.push(2);

        q.offer(0);
        q.offer(1);
        q.offer(2);

        System.out.println("==Stack==");
        while(!st.isEmpty()) {
            System.out.println(st.pop());
        }

        System.out.println("==Queue==");
        while(!q.isEmpty()) {
            System.out.println(q.poll());
        }
    }
}

실행결과

 

Stack은 마지막에 넣은 걸 꺼내고, Queue는 처음 넣은 걸 꺼내는 것을 확인할 수 있다.

 

 

 

 

예시2

import java.util.*;

public class StackQueue_Ex2 {
    public static void main(String[] args) {
        Stack st = new Stack();
        String expr = "((3+5)*2)-4)";

        System.out.println("expression : " + expr);

        try {
            for (int i = 0; i < expr.length(); i++) {
                char ch = expr.charAt(i);

                if (ch == '(') {
                    st.push(ch);
                } else if (ch == ')') {
                    st.pop();
                }
            }

            if (st.isEmpty()) {
                System.out.println("괄호가 일치");
            } else {
                System.out.println("괄호가 불일치(여는 괄호가 더 많음)");
            }
        } catch (EmptyStackException e) {
            System.out.println("괄호 불일치(닫는 괄호가 더 많음)");
        }
    }
}

import java.util.*;

public class StackQueue_Ex2 {
    public static void main(String[] args) {
        Stack st = new Stack();
        String expr = "((3+5)*2)-4)";

        System.out.println("expression : " + expr);

        try {
            for (int i = 0; i < expr.length(); i++) {
                char ch = expr.charAt(i);

                if (ch == '(') {
                    st.push(ch);
                } else if (ch == ')') {
                    st.pop();
                }
            }

            if (st.isEmpty()) {
                System.out.println("괄호가 일치");
            } else {
                System.out.println("괄호가 불일치(여는 괄호가 더 많음)");
            }
        } catch (EmptyStackException e) {
            System.out.println("괄호 불일치(닫는 괄호가 더 많음)");
        }
    }
}

Stack을 사용하여 괄호 매칭을 검사하는 코드이다.

expr에 원하는 문자열을 넣고 실행하면 괄호가 올바르게 매칭됐는지 확인할 수 있다.

try문 안에서 반복문을 돌면서 여는 괄호가 있으면 스택에 추가해주고, 닫는 괄호를 만나면 스택에서 꺼낸다.

Stack을 모두 순회하고 나고 스택이 비어있으면 괄호 매칭이 된 것이고, 스택 안에 요소가 남아있으면 닫는 괄호가 부족해서 여는 괄호를 pop하지 못한 경우이다.

여는 괄호보다 닫는 괄호가 많으면 pop을 할 때 스택 안에 요소가 없기 때문에 예외가 발생한다.

실행결과

 

 

예시3

import java.util.*;
public class StackQueue_Ex3 {
    static Queue q = new LinkedList();
    static final int MAX_SIZE = 5;

    public static void main(String[] args) {
        System.out.println("help입력 시 도움말");

        while(true) {
            System.out.print(">> ");
            try {
                //화면에서 라인단위로 입력 받기
                Scanner s = new Scanner(System.in);
                String input = s.nextLine().trim(); // trim으로 앞 뒤 공백 제거

                if ("".equals(input)) continue;

                if (input.equalsIgnoreCase("q")) {
                    System.exit(0); //q입력하면 프로그램 종료
                } else if (input.equalsIgnoreCase("help")) {
                    System.out.println("help - 도움말");
                    System.out.println("q - 프로그램 종료");
                    System.out.println("history - 최근 입력한 명령어 " + MAX_SIZE + "개 보여준다.");
                } else if (input.equalsIgnoreCase("history")) {
                    save(input);
                    LinkedList list = (LinkedList) q;

                    final int SIZE = list.size(); // 반복문이 도는 동안 size는 변하지 않아서 반복문 밖에 상수 정의
                    for (int i = 0; i < SIZE; i++) {
                        System.out.println((i + 1) + "." + list.get(i));
                        // history입력시 입력했던 명령어들 출력
                    }
                } else {
                    save(input);
                    System.out.println(input);
                }
            } catch(Exception e) {
                System.out.println("입력 오류");
            }
        }
    }

    public static void save(String input) {
        // queue에 저장하는 메소드

        if (!"".equals(input)) // if (input != null && input.equals(""))와 같음, equals(null)은 괜찮음
            q.offer(input);
        // 빈문자열은 queue에 추가 x

        if (q.size() > MAX_SIZE)
            q.poll();
    }
}

queue를 사용해서 입력한 명령어를 5개까지 저장하고, 보여주는 프로그램이다.

실행결과

 

MAX_SIZE로 정한 5가 넘어가면 맨 처음 들어온 명령어를 poll하고 새로운 명령어를 넣어준다.