Repository

명품자바 5장 실습문제 12번 (LinkedList)

dev_zephyr 2021. 1. 27. 18:42

연결리스트(LinkedList)를 직접 구현하는 문제로 해석했다.

prev, next 등 node의 개념이 완전하지 않아 그림을 계속 그려가며 구현했던 기억이 난다.

연결리스트도 빡센데 추상클래스, 상속까지 더해져 꽤 고전했었던 난이도 있는 문제였다.

 

 

 

 

 

import java.util.InputMismatchException;
import java.util.Scanner;

abstract class Shape {
	private Shape next;
	
	public Shape() {
		next = null;
	}
	
	public void setNext(Shape obj) {
		next = obj;
	}
	
	public Shape getNext() {
		return next;
	}
	
	public abstract void draw();
}

class Line extends Shape {

	public Line() {
		super();
	}
	
	@Override
	public void draw() {
		System.out.println("Line");
	}
	
}

class Rect extends Shape {

	public Rect() {
		super();
	}
	
	@Override
	public void draw() {
		System.out.println("Rect");
	}
	
}

class Circle extends Shape {

	public Circle() {
		super();
	}
	
	@Override
	public void draw() {
		System.out.println("Circle");
	}
	
}

class GraphicEditor {
	Scanner scan = new Scanner(System.in);
	Shape head, tail;
	int nodeSize = 0;
	int choice;
	
	public GraphicEditor() {
		tail = null;
		run();
	}
	
	public void run() {
		System.out.println("그래픽 에디터 beauty를 실행합니다.");
		while(true) {
			System.out.print("삽입(1), 삭제(2), 모두 보기(3), 종료(4)>> ");
			choice = validateChoice(4); // 제대로 된 숫자를 입력받기위해
			
			switch(choice) {
			case 1 :
				System.out.print("Line(1), Rect(2), Circle(3)>> ");
				choice = validateChoice(3);
				add(choice);
				break;
			case 2 : 
				System.out.print("삭제할 도형의 위치>> ");
				choice = validateChoice(nodeSize);
				delete(choice); 
				break;
			case 3 : 
				showAll(); 
				break;
			case 4 : 
				exit(); 
				break;
			}
		}
	}
	
	public int validateChoice(int limit) { // 잘못된숫자입력, 예외처리 한방에 하는 method
		while(true) {
			try {
				
				int tmp = scan.nextInt();
				if(tmp < 1 || tmp > limit) { //  메뉴에 없는 입력값을 받으면 다시 받는다
					System.out.print("잘못 입력하셨습니다. 다시입력하세요>> ");
					continue;
				} else {
					return tmp;
				}
			} catch (InputMismatchException e) { // 숫자 말고 다른거 눌렀을때 다시 받는다
				System.out.print("잘못 입력하셨습니다. 다시입력하세요>> ");
				scan.nextLine();
				continue;
			}
		}
	}
	
	public void add(int choice) {
		switch(choice) {
		case 1: 
			addNode(new Line()); 
			break;
		case 2: 
			addNode(new Rect());
			break;
		case 3:
			addNode(new Circle());
			break;
		}
	}
	
	public void addNode(Shape obj) {
		// Linked_List개념에서 처음 시작 객체의 주소를 잃어버리면 아예 모든 객체에 접근할 방법이 없어지기때문에
		// 처음 시작 객체의 주소를 담고있는 head는 유지되어야 한다.
		
		if(head == null) { // 처음 입력받을때
			Shape node = obj; //노드(객체)생성
			head = node;		// 헤드는 객체가 된다.(첫번째 객체이므로)
			nodeSize++;
			tail = node;   // 처음 객체가 마지막 객체다. 
			
		} else {			// 처음 입력이 아닐때 
			Shape node = obj; // 노드(객체) 생성
			tail.setNext(node); // tail(마지막객체)의 next를 현재 만든 객체로 참조하고
			tail = node;        // tail은 마지막객체를 참조한다.
			nodeSize++;
		}
	}
	
	public void delete(int choice) {
		int index = choice - 1;
		Shape node = head;
		if(index == 0) { //처음 입력한 객체를 지울때
			head = node.getNext(); // head(시작)은 2번째 객체부터.
		}
		for(int i=0; i<index-1; i++) {	//삭제하고자 하는 번지의 전까지 이동한다.
			node = node.getNext();
		}
		node.setNext(node.getNext().getNext());	 // 다음다음 노드로 바로 연결하면 다음노드는 가르키는 참조변수가 없으므로 삭제(가비지)된다.
												// ex) 1-2-3-4-5에서 3을 지우려면 1-2-4-5처럼 2에서 바로 4로 연결시킨다.
	}
	
	public void showAll() {
		Shape node = head;
		while(node != null) { 
			node.draw();		//head부터 draw() 하고
			node = node.getNext(); // 그 객체가 참조하는 next(다음객체)를 node에 담고 계속 반복한다. 
		}
		
	}
	
	public void exit() {
		System.out.println("beauty를 종료합니다.");
		System.exit(0);
	}
}


public class Exercise12_2 {
	public static void main(String[] args) {
		
		new GraphicEditor();
		
	}
}

 

 

결과