πŸ—„οΈ Backend/Java

μžλ°”(Java) - μ»¬λ ‰μ…˜ ν”„λ ˆμž„μ›Œν¬(6) (Stack)LIFO, (Queue)FIFO

kongmi 2023. 2. 2. 19:45

Stack?

  • LIFO(Last in First Out) ꡬ쑰, μŠ€νƒμ„ μ΄μš©ν•œ λŒ€ν‘œμ μΈ μ˜ˆμ‹œλ‘œ JVM의 μŠ€νƒ λ©”λͺ¨λ¦¬λ₯Ό λ“€ 수 μžˆμŠ΅λ‹ˆλ‹€.
  • μŠ€νƒ λ©”λͺ¨λ¦¬μ— μ €μž₯된 λ³€μˆ˜λŠ” λ‚˜μ€‘μ— μ €μž₯된 것 λΆ€ν„° λ¨Όμ € 제거 λ©λ‹ˆλ‹€.
  • μŠ€νƒμ€ λ‚΄λΆ€μ μœΌλ‘œ Vector 클래슀λ₯Ό 상속 λ°›μ•„ λ§Œλ“€μ–΄ μ‘ŒμŠ΅λ‹ˆλ‹€.
  •  ν”„λ‘œκ·Έλž¨ λ‚΄μ—μ„œ λ©”μ†Œλ“œμ˜ 호좜이 μŒ“μ΄λŠ” ꡬ쑰에 μ‚¬μš© λ©λ‹ˆλ‹€.
  • μž…λ ₯κ³Ό 좜λ ₯이 ν•œ κ³³μ—μ„œλ§Œ μΌμ–΄λ‚©λ‹ˆλ‹€.

κ΄€λ ¨ λ©”μ†Œλ“œ

  1. push() : 객체λ₯Ό μ €μž₯ ν•©λ‹ˆλ‹€.
    public E push(E item)
  2. peek() : μŠ€νƒ 맨 μœ„μ˜ κ°’ 확인
  3. pop() : μŠ€νƒμ˜ 맨 μœ„μ˜ 값을 μΆ”μΆœν•˜λ©΄μ„œ λ³΄μ—¬μ€Œ
    public E pop() 
    ➑️ Removes the object at the top of this stack and returns that object as the value of this function.
  4. empty() : μŠ€νƒμ΄ λΉ„μ–΄ μžˆλŠ”μ§€ 확인 ν›„ boolean으둜 λ°˜ν™˜
  5. size() : μŠ€νƒμ— ν¬ν•¨λœ 객체 개수 λ°˜ν™˜(int)
  6. contains(Object o) : ν•΄λ‹Ή κ°’(Object o)이 μŠ€νƒ μ•ˆμ— μžˆλŠ”μ§€ boolean으둜 λ°˜ν™˜
    public boolean contains(Object o)

🐢기본 예제1

import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        System.out.println(stack.peek());
        System.out.println(stack.pop());
        System.out.println(stack.empty());
        System.out.println(stack.size());
        System.out.println(stack.contains(1));
    }
}
3
3
false
2
true

πŸΆμ‘μš© 예제(동전)

import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Stack<Coin> coinBox = new Stack<>();
        coinBox.push(new Coin(100));
        coinBox.push(new Coin(50));
        coinBox.push(new Coin(500));
        coinBox.push(new Coin(10));
        while(!coinBox.isEmpty()) {
            Coin coin = coinBox.pop();
            System.out.println("κΊΌλ‚΄ 온 동전 : " + coin.getValue());
        }
    }
}

class Coin {
    private int value;

    public Coin(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}
κΊΌλ‚΄ 온 동전 : 10
κΊΌλ‚΄ 온 동전 : 500
κΊΌλ‚΄ 온 동전 : 50
κΊΌλ‚΄ 온 동전 : 100

πŸΆμ‘μš© 예제2 (κ΄„ν˜Έ)

import java.util.Scanner;
import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Stack<Character> st = new Stack<>();
        Scanner sc = new Scanner(System.in);
        System.out.print("μˆ˜μ‹ μž…λ ₯ : ");
        String exp = sc.next();
        for(int i = 0; i < exp.length(); i++) {
            char ch = exp.charAt(i);
            if (ch == '(') { // μ—΄λ¦Ό κ΄„ν˜ΈμΌ λ•Œ push
                st.push(ch);
            } else if (ch == ')') { // λ‹«νž˜ κ΄„ν˜ΈμΌ λ•Œ
                if (!st.isEmpty()) st.pop(); // stack이 λΉ„μ–΄μžˆμ§€ μ•ŠμœΌλ©΄ pop
                else {
                    System.out.println("κ΄„ν˜Έκ°€ μΌμΉ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.");
                    return;
                }
            }
        }
        if(st.isEmpty()) {
            System.out.println("κ΄„ν˜Έκ°€ 일치 ν•©λ‹ˆλ‹€.");
        } else {
            System.out.println("κ΄„ν˜Έκ°€ 일치 ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.");
        }
    }
}
μˆ˜μ‹ μž…λ ₯ : ((3+4)*6)
κ΄„ν˜Έκ°€ 일치 ν•©λ‹ˆλ‹€.
μˆ˜μ‹ μž…λ ₯ : ((3+4) *6))
κ΄„ν˜Έκ°€ 일치 ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

Queue?

  • FIFO(First In First Out) ꡬ쑰
  • LinkedList ꡬ쑰λ₯Ό μ‚¬μš©ν•˜κ³  있으며, LinkedList κΈ°λŠ₯ 쀑 Queue κ΄€λ ¨ κΈ°λŠ₯으둜 μ œν•œλ¨

κ΄€λ ¨ λ©”μ†Œλ“œ

Summary of Queue methods

  Throws exception Returns special value
Insert add(e) offer(e)
Remove remove() poll()
Examine element() peek()

(1) Parameters: e

    the element to add

πŸ’‘ In a FIFO queue, all new elements are inserted at the tail of the queue.

  1. add(e) : 맨 λ’€ μœ„μΉ˜μ— μš”μ†Œλ₯Ό μ‚½μž…(쀑간 μ‚½μž… X) - μ˜ˆμ™Έ λ°œμƒ
    βœ… Inserts the specified element into this queue if it is possible to do so immediately without violating capacity restrictions, returning true upon success and throwing an IllegalStateException if no space is currently available.
  2. offer(e) : 맨 λ’€ μœ„μΉ˜μ— μš”μ†Œλ₯Ό μ‚½μž…
    βœ… The offer method inserts an element if possible, otherwise returning false.
    βœ… The offer method is designed for use when failure is a normal, rather than exceptional occurrence, for example, in fixed-capacity (or "bounded") queues.

(2) Retrieves and removes the head of this queue.

    return the head of this queue

  1. remove() - λΉ„μ–΄μžˆμœΌλ©΄ μ˜ˆμ™Έ λ°œμƒ
  2. poll() - λΉ„μ–΄μžˆμœΌλ©΄ null λ°˜ν™˜

πŸ’‘The remove() and poll() methods differ only in their behavior when the queue is empty: the remove() method throws an exception, while the poll() method returns null.

 

(3) Retrieves, but does not remove, the head of this queue.

    return the head of this queue

  1. element() - 맨 μ•žμ˜ μš”μ†Œλ₯Ό μ½μ–΄μ˜΄ - μ˜ˆμ™Έ λ°œμƒ
    βœ… This method differs from peek only in that it throws an exception if this queue is empty.
  2. peek() - 맨 μ•žμ˜ μš”μ†Œλ₯Ό μ½μ–΄μ˜΄ - λΉ„μ–΄ 있으면 null λ°˜ν™˜
    βœ…
    the head of this queue, or null if this queue is empty

🐢기본 예제1

import java.util.LinkedList;
import java.util.Queue;

public class Main {
    public static void main(String[] args) {
        Queue<Message> msgQ = new LinkedList<>();
        msgQ.offer(new Message("Mail", "홍길동"));
        msgQ.add(new Message("SMS", "ν•œμ„λ΄‰"));
        msgQ.offer(new Message("Kakao", "였재미"));
        while(!msgQ.isEmpty()) {
            Message msg = msgQ.poll(); // νμ—μ„œ ν•œκ°œμ˜ λ©”μ‹œμ§€λ₯Ό 꺼냄(λ§¨μ•ž)
            switch(msg.command) {
                case "Mail" : System.out.println(msg.to + "μ—κ²Œ 메일을 λ³΄λƒ…λ‹ˆλ‹€."); break;
                case "SMS" : System.out.println(msg.to + "μ—κ²Œ 문자λ₯Ό λ³΄λƒ…λ‹ˆλ‹€."); break;
                case "Kakao" : System.out.println(msg.to + "μ—κ²Œ μΉ΄μΉ΄μ˜€ν†‘μ„ λ³΄λƒ…λ‹ˆλ‹€."); break;
            }
        }
    }
}

class Message {
    String command;
    String to;

    public Message(String command, String to) {
        this.command = command;
        this.to = to;
    }
}
ν™κΈΈλ™μ—κ²Œ 메일을 λ³΄λƒ…λ‹ˆλ‹€.
ν•œμ„λ΄‰μ—κ²Œ 문자λ₯Ό λ³΄λƒ…λ‹ˆλ‹€.
μ˜€μž¬λ―Έμ—κ²Œ μΉ΄μΉ΄μ˜€ν†‘μ„ λ³΄λƒ…λ‹ˆλ‹€.

πŸΆμ‘μš© 예제(λͺ…λ Ή 이λ ₯ 쑰회)

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {
    Queue<String> queue = new LinkedList<>();
    final static int MAX_SIZE = 10;

    public static void main(String[] args) {
        Main history = new Main();
        System.out.println("helpλ₯Ό μž…λ ₯ν•˜λ©΄ 도움말을 λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.");
        while(true) {
            System.out.print("$ ");
            Scanner sc = new Scanner(System.in);
            String cmd = sc.nextLine().trim(); // μž…λ ₯ 받은 λ¬Έμžμ—΄μ˜ μ•žλ’€μ˜ 곡백 제거
            if(cmd.equalsIgnoreCase("q")) {
                System.exit(0); // ν”„λ‘œκ·Έλž¨ κ°•μ œμ’…λ£Œ (return 보닀 κ°•λ ₯)
            } else if(cmd.equalsIgnoreCase("help")) {
                System.out.println("help - 도움말을 λ³΄μ—¬μ€λ‹ˆλ‹€.");
                System.out.println("q/Q - ν”„λ‘œκ·Έλž¨ μ’…λ£Œ");
                System.out.println("history - 졜근 μž…λ ₯ν•œ λͺ…λ Ήμ–΄λ₯Ό " + MAX_SIZE + "개 λ³΄μ—¬μ€λ‹ˆλ‹€.");
            } else if(cmd.equalsIgnoreCase("history")) {
                history.save(cmd);
                int cnt = 0;
                for(String e : history.queue) {
                    cnt++;
                    System.out.println(cnt + " " + e);
                }
            } else {
                history.save(cmd);
                System.out.println(cmd);
            }
        }
    }
    void save(String cmd) {
        queue.offer(cmd);
        if(queue.size() > MAX_SIZE) queue.remove(); // 큐의 κ°œμˆ˜κ°€ λ„˜μ–΄κ°€λ©΄ 맨 μ•žμ˜ μš”μ†Œ 제거
    }
}