Java

11.09.(수) Java-15: 스택

콜라든포비 2022. 11. 9. 21:50

스택

스택은 배열의 한 종류로, 출력방식에서의 차이가 있을 뿐이다.

스택은 임시로 데이터를 저장하는 기능을 가지며, 나중에 입력된 데이터를 먼저 출력할 수 있는 기능을 가진다.

이런 특성을 LIFO(Last In First Out) 혹은 FILO(First In Last Out)이라고 부른다.

출력하고난 뒤에 데이터는 스택에서 제거된다.

 

스택 메소드

  • push : 스택에 데이터 담기
  • pop : 스택의 맨 위에 있는 데이터 꺼내기
  • peek : 스택의 맨 위에 있는 데이터 반환하기
  • dump : 스택의 정보 알아내기
  • search : 입력한 데이터가 위치한 index값 구하기
  • empty : 스택내의 모든 데이터 지우기

위 메소드를 이용해서 스택이 어떻게 생겼는지 알아보자.

메소드를 구성하는 구현클래스와 실행클래스 두개로 나누어 코드를 짰다.

package sw.search;

public class IntStack {
	private int capacity;	// 배열의 크기
	private int[] stk;	// 데이터를 담을 배열
	private int ptr = 0;	// 스택의 포인터 : 멤버영역일때 초기값 자동설정됨
	
	// 생성자 메소드
	public IntStack(int capacity) {
		this.stk = new int[capacity];	// 전달받은 매개변수를 stk배열의 크기로 설정
		this.capacity = capacity;
	}
	
	// push 메소드
	public int push(int inData) throws OverflowIntStackException {
		// 오버플로우(데이터가 넘칠때) 예외처리
		if(this.capacity==this.ptr) {	// 배열의 크기 = 최대 index 일때
			throw new OverflowIntStackException(); 
		}
		return stk[ptr++] = inData;	// ptr위치에 data를 담고, ptr은 1증가 시킨다
	}
	
	// pop 메소드
	public int pop() throws EmptyIntStackException{
		if(this.ptr==0) {
			throw new EmptyIntStackException();
		}
		return stk[--ptr];	// 가장 마지막으로 저장된 값 (제일 위에 있는 값)을 꺼낸다
	}
	
	// peek 메소드
	public int peek() throws EmptyIntStackException{
		if(this.ptr==0) {
			throw new EmptyIntStackException();
		}
		return stk[ptr-1];	// 원래 ptr값은 유지
	}
	
	// dump 메소드
	public void dump() throws EmptyIntStackException{
		if(this.ptr==0) {
			throw new EmptyIntStackException();
		}
		for(int i=0; i<ptr; i++) {
			System.out.println("stk[" + i + "] = " + stk[i]);
		}
	}
	
	// search 메소드
	public int indexOf(int searchData) {
		for(int i=ptr-1; i>=0; i--) {
			if(stk[i]==searchData) {
				return i;
			}
		}
		return -1;
	}
	
	// empty 메소드
	public void makeEmpty() {
		ptr = 0;	// 포인터 처음 위치로 돌려주면 초기화가 된다
	}
	
	// info 용량 메소드
	public int capacity() {
		return this.capacity;
	}
	
	// info 데이터 수 메소드
	public int size() {
		return ptr;
	}
	
	// info empty여부
	public boolean isEmpty() {
		if(ptr==0) {
			return true;
		}else {
			return false;
		}
	}
	
	// 오버플로우 발생 시 처리할 예외내부클래스 생성
	public class OverflowIntStackException extends RuntimeException{
		public OverflowIntStackException() {}
	}
	
	// 스택이 비었을 처리할 예외내부클래스 생성
		public class EmptyIntStackException extends RuntimeException{
			public EmptyIntStackException() {}
	}
}
package sw.search;

import java.util.Scanner;

public class IntStackMain {
	public static Scanner sc = new Scanner(System.in);
	
	public static void startStack() {
		IntStack stack = new IntStack(5);	// 스택 객체를 생성하고, 스택의 크기를 설정할 수 있음
		
		do {
			// 메뉴 작성하기
			System.out.print("(1) PUSH  (2) POP  (3) PEEK  (4) DUMP  (5) SEARCH  (6) EMPTY  (7) INFO  (0) 종료 -> ");
			int menu = sc.nextInt();
			
			if(menu==0) {
				System.out.println("종료했습니다.");
				break;
			}	// 종료
			
			switch(menu) {
			case 1:
				// push : 데이터를 스택에 담기
				System.out.print("데이터 입력 : ");
				int inData = sc.nextInt();
				try {
					stack.push(inData);
				}catch(IntStack.OverflowIntStackException e) {
					System.out.println("스택이 가득 찼습니다.");
				}
				break;
			case 2:
				// pop : 스택에서 제일 마지막으로 저장된 값 꺼내기
				try {
					int popData = stack.pop();
					System.out.println(popData + " 꺼냄.");
				}catch(IntStack.EmptyIntStackException e) {
					System.out.println("스택이 비었습니다.");
				}
				break;
			case 3:
				// peek : 스택에서 제일 마지막으로 저장된 값 구하기
				try {
					int topData = stack.peek();
					System.out.println("마지막으로 담긴 데이터 : " + topData);
				}catch(IntStack.EmptyIntStackException e) {
					System.out.println("스택이 비었습니다.");
				}
				break;
			case 4:
				// dump : 스택의 정보 알아내기
				try {
					stack.dump();
				}catch(IntStack.EmptyIntStackException e) {
					System.out.println("스택이 비었습니다.");
				}
				break;
			case 5:
				// search : 입력한 데이터가 위치한 index값 구하기
				System.out.print("검색값 : ");
				int searchData = sc.nextInt();
				int idx = stack.indexOf(searchData);
				if(idx>=0) {	// 스택에 데이터가 있을 때
					System.out.println(searchData + "은(는) " + idx + "번 index위치에 있습니다.");
				}else {		// 스택에 데이터가 없을 때
					System.out.println(searchData + "은(는) 없습니다.");
				}
				break;
			case 6:
				// empty : 스택 내의 모든 데이터를 지우기
				stack.makeEmpty();
				break;
			case 7:
				// info : 용량, 데이터 수, 데이터 정보, empty 여부
				System.out.println("저장 가능한 데이터 수 : " + stack.capacity());	// 용량
				System.out.println("현재 데이터 수 : " + stack.size());
				try {
					stack.dump();
				}catch(StackInt.EmptyIntStackException e) {}
				System.out.println("스택이 " + (stack.isEmpty() ? "비어있습니다.":"비어있지 않습니다."));
				
				break;
			default:
				// 메뉴를 잘못 선택했습니다.
				System.out.println("메뉴를 잘못 입력하였습니다. 0~8 사이의 값을 입력하세요.");
			}
		}while(true);
	}
	
	public static void main(String[] args) {
		startStack();
	}
}