<명품 JAVA Programming> - Chapter7 실습문제

1. Scanner 클래스로 -1이 입력될 때까지 양의 정수를 입력받아 벡터에 저장하고 벡터를 검색하여 가장 큰 수를 출력하는 프로그램을 작성하라.

 

package chapter7;
import java.util.*;

public class Max {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		Vector<Integer> v = new Vector<Integer>();
		
		System.out.print("정수(-1이 입력될 때까지)>> ");
		while(true) {
			int n = sc.nextInt();
			if(n == -1) break;
			v.add(Integer.valueOf(n));	//v.add(n);
		}
		
		int max = v.get(0);
		for(int i = 1; i < v.size(); i++) {
			if (max < v.get(i)) max = v.get(i);
		}
		
		System.out.println("가장 큰 수는 " + max);
		
		sc.close();
	}
}

 

 

2. Scanner 클래스를 사용하여 6개 학점('A', 'B', 'C', 'D', 'F')을 문자로 입력받아 ArrayList에 저장하고, ArrayList를 검색하여 학점을 점수(A=4.0, B=3.0, C=2.0, D=1.0, F=0)로 변환하여 평균을 출력하는 프로그램을 작성하라.

 

package chapter7;
import java.util.*;

public class Average {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		ArrayList<Character> a = new ArrayList<Character>();
		
		System.out.print("6개의 학점을 빈 칸으로 분리 입력(A/B/C/D/E/F)>>");
		for(int i = 0; i < 6; i++) {
			char grade = sc.next().charAt(0);
			a.add(Character.valueOf(grade));	//a.add(grade);
		}
		
		double sum = 0;
		for(int i = 0; i < 6; i++) {
			if(a.get(i).equals('A')) sum += 4.0;
			else if(a.get(i).equals('B')) sum += 3.0;
			else if(a.get(i).equals('C')) sum += 2.0;
			else if(a.get(i).equals('D')) sum += 1.0;
			else if(a.get(i).equals('F')) sum += 0.0;
		}
		System.out.println(sum / 6);
		
		sc.close();
	}
}

 

 

3."그만"이 입력될 때까지 나라 이름과 인구를 입력받아 저장하고 다시 나라 이름을 입력받아 인구를 출력하는 프로그램을 작성하라. 다음 해시맵을 이용하라.

 

package chapter7;
import java.util.*;

public class Country {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		HashMap<String, Integer> nations = new HashMap<String, Integer>();
		System.out.println("나라 이름과 인구를 입력하세요.(예: Korea 5000)");
		
		//입력
		while(true) {
			System.out.print("나라 이름, 인구>>");
			String name = sc.next();
			if(name.equals("그만")) break;
			int population = sc.nextInt();
			
			nations.put(name, population);
		}
		
		//검색
		while(true) {
			System.out.print("인구검색>>");
			String name = sc.next();
			
			if(name.equals("그만")) break;
			if(nations.get(name) == null)
				System.out.println(name + "국가는 없습니다.");
			else
				System.out.println(name + "의 인구는 " + nations.get(name));
		}
		System.out.println("종료합니다.");
		sc.close();
	}
}

 

 

4. Vector 컬렉션을 이용하여 강수량의 평균을 유지 관리하는 프로그램을 작성하라. 강수량을 입력하면 벡터에 추가하고 현재 입력된 모든 강수량과 평균을 출력한다.

 

package chapter7;
import java.util.*;

public class Precipitation {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		Vector<Integer> pre = new Vector<Integer>();
		
		while(true) {
			double sum = 0;
			System.out.print("강수량 입력(0 입력 시 종료)");
			int n = sc.nextInt();
			if (n == 0) break;
			
			pre.add(n);
			for(int i = 0; i < pre.size(); i++) {
				System.out.print(pre.get(i) +" ");
				sum += pre.get(i);
			}
			System.out.println();
			System.out.println("현재 평균 " + sum / pre.size());
		}
		sc.close();
	}
}

 

 

5. 하나의 학생 정보를 나타내는 Student 클래스에는 이름, 학과, 학번, 학점 평균을 저장하는 필드가 있다.

(1) 학생마다 Student 객체를 생성하고 4명의 학생 정보를 ArrayList<Student> 컬렉션에 저장한 후에, ArrayList<Student>의 모든 학생(4명) 정보를 출력하고 학생 이름을 입력받아 해당 학생의 학점 평균을 출력하는 프로그램을 작성하라.

(2)ArrayList<Student> 대신, HashMap<String,Student>해시맵을 이용하여 다시 작성하라. 해시맵에서 키는 학생 이름으로 한다.

 

1)

package chapter7;
import java.util.*;

class Student {
	private String name, major, sNumber;
	private double grade;
	public Student(String name, String major, String sNumber, double grade) {
		this.name = name;
		this.major = major;
		this.sNumber = sNumber;
		this.grade = grade;
	}
	public String getName() {
		return name;
	}
	public String getMajor() {
		return major;
	}
	public String getsNumber() {
		return sNumber;
	}
	public double getGrade() {
		return grade;
	}
}
public class StudentInfo {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		ArrayList<Student> info = new ArrayList<Student>();
		
		System.out.println("학생 이름, 학과, 학번, 학점 평균을 입력하세요.");
		for(int i = 0; i < 4; i++) {
			System.out.print(">> ");
			String text = sc.nextLine();
			StringTokenizer st = new StringTokenizer(text, ",");
			String name = st.nextToken().trim();
			String major = st.nextToken().trim();
			String sNumber = st.nextToken().trim();
			double grade = Double.parseDouble(st.nextToken().trim());
			
			Student s = new Student(name, major, sNumber, grade);
			info.add(s);
		}
		
		Iterator<Student> it = info.iterator();
		while (it.hasNext()) {
			Student student = it.next();
			System.out.println("---------------------------");
			System.out.println("이름:" + student.getName());
			System.out.println("학과:" + student.getMajor());
			System.out.println("학번:" + student.getsNumber());
			System.out.println("학점평균:" + student.getGrade());
			System.out.println("---------------------------");
		}	
		
		while(true) {
			System.out.print("학생 이름 >> ");
			String name = sc.nextLine();
			if(name.equals("그만")) break;
			
			for(int i = 0; i < info.size(); i++) {
				Student s = info.get(i);
				if(s.getName().equals(name)) {
					System.out.print(s.getName() + ", ");
					System.out.print(s.getMajor() + ", ");
					System.out.print(s.getsNumber() + ", ");
					System.out.println(s.getGrade());
					break;
				}
			}
		}
		sc.close();
	}	
}

 

2)

package chapter7;
import java.util.*;

class Student2 {
	private String name, major, sNumber;
	private double grade;
	public Student2(String name, String major, String sNumber, double grade) {
		this.name = name;
		this.major = major;
		this.sNumber = sNumber;
		this.grade = grade;
	}
	public String getName() {
		return name;
	}
	public String getMajor() {
		return major;
	}
	public String getsNumber() {
		return sNumber;
	}
	public double getGrade() {
		return grade;
	}
}
public class StudentInfo2 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		HashMap<String, Student> info = new HashMap<String, Student>();
		
		System.out.println("학생 이름, 학과, 학번, 학점 평균을 입력하세요.");
		for(int i = 0; i < 4; i++) {
			System.out.print(">> ");
			String text = sc.nextLine();
			StringTokenizer st = new StringTokenizer(text, ",");
			String name = st.nextToken().trim();
			String major = st.nextToken().trim();
			String sNumber = st.nextToken().trim();
			double grade = Double.parseDouble(st.nextToken().trim());
			
			Student s = new Student(name, major, sNumber, grade);
			info.put(name, s);
		}
		
		Set<String> key = info.keySet();	//해시맵 info에 있는 모든 키 Set 컬렉션으로 리턴
		Iterator<String> it = key.iterator();	//Set을 순차검색하는 이터레이터 리턴
		while (it.hasNext()) {
			String name = it.next();
			Student student = info.get(name);	//이름을 키로 하여 객체를 얻는다.
			System.out.println("---------------------------");
			System.out.println("이름:" + student.getName());
			System.out.println("학과:" + student.getMajor());
			System.out.println("학번:" + student.getsNumber());
			System.out.println("학점평균:" + student.getGrade());
			System.out.println("---------------------------");
		}	
		
		while(true) {
			System.out.print("학생 이름 >> ");
			String name = sc.nextLine();
			if(name.equals("그만")) break;
			
			Student student = info.get(name); // 해시맵에서 이름을 키로 검색
			if(student == null) { // 이름이 해시맵에 없다면
				System.out.println(name + " 학생 없습니다.");
			}
			else { // 해시맵에서 검색된  Student 객체
				System.out.print(student.getName() + ", ");
				System.out.print(student.getMajor() + ", ");
				System.out.print(student.getsNumber() + ", ");
				System.out.println(student.getGrade());
			}
		}
		sc.close();
	}	
}

 

 

6. 도시 이름, 위도, 경도 정보를 가진 Location 클래스를 작성하고, 도시 이름을 '키'로 하는 HashMap<String, Location> 컬렉션을 만들고, 사용자로부터 입력 받아 4개의 도시를 저장하라. 그리고 도시 이름으로 검색하는 프로그램을 작성하라.

 

package chapter7;
import java.util.*;

class Location {
	private String name;
	private int longitude, latitude;	//경도, 위도
	public Location(String name, int longitude, int latitude) {
		this.name = name;
		this.longitude = longitude;
		this.latitude = latitude;
	}
	public String getName() {
		return name;
	}
	public int getLongitute() {
		return longitude;
	}
	public int getLatitude() {
		return latitude;
	}
}

public class SearchCity {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		HashMap<String, Location> info = new HashMap<String, Location>();
		
		System.out.println("도시, 경도, 위도를 입력하세요.");
		
		for(int i = 0; i < 4; i++) {
			System.out.print(">> ");
			String text = sc.nextLine();
			StringTokenizer st = new StringTokenizer(text, ",");
			String name = st.nextToken().trim();
			int longitude = Integer.parseInt(st.nextToken().trim());
			int latitude = Integer.parseInt(st.nextToken().trim());

			Location location = new Location(name, longitude, latitude);
			info.put(name, location);
		}
		
		Set<String> key = info.keySet();	//해시맵 info에 있는 모든 키 Set 컬렉션으로 리턴
		Iterator<String> it = key.iterator();	//Set을 순차검색하는 이터레이터 리턴
		System.out.println("---------------------------");
		while (it.hasNext()) {
			String name = it.next();
			Location location = info.get(name);	//이름을 키로 하여 객체를 얻는다.
			System.out.print(location.getName() + " ");
			System.out.print(location.getLongitute() + " ");
			System.out.println(location.getLatitude() + " ");
		}	
		System.out.println("---------------------------");
		
		while(true) {
			System.out.print("도시 이름 >> ");
			String name = sc.nextLine();
			if(name.equals("그만")) break;
			
			Location location = info.get(name); // 해시맵에서 이름을 키로 검색
			if(location == null) { // 이름이 해시맵에 없다면
				System.out.println(name + "는 없습니다.");
			}
			else { // 해시맵에서 검색된  Student 객체
				System.out.print(location.getName() + " ");
				System.out.print(location.getLongitute() + " ");
				System.out.println(location.getLatitude());
			}
		}
		sc.close();
	}
}

 

 

7. 이름과 학점(4.5만점)을 5개 입력받아 해시맵에 저장하고, 장학생 선발 기준을 입력받아 장학생 명단을 출력하라.

 

package chapter7;
import java.util.*;

public class Scholarship {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		HashMap<String, Double> student = new HashMap<String, Double>();
		
		System.out.println("미래장학금관리시스템입니다.");
		for(int i = 0; i < 5; i++) {
			System.out.print("이름과 학점>> ");
			String name = sc.next();
			double grade = sc.nextDouble();
			student.put(name, grade);
		}
		System.out.print("장학생 선발 학점 기준 입력>> ");
		double standard = sc.nextDouble();
		
		System.out.print("장학생 명단: ");
		Set<String> keys = student.keySet();
		Iterator<String> it = keys.iterator();
		while(it.hasNext()) {
			String key = it.next();
			double value = student.get(key);
			if(value >= standard)
				System.out.print(key + " ");
		}
		sc.close();
	}
}

 

 

8. 고객의 이름과 포인트 점수를 관리하는 프로그램을 해시맵을 이용하여 작성하라. 프로그램은 고객의 이름과 포인트를 함께 저장 관리하는데, 포인트는 추가될 때마다 누적하여 저장된다.

 

package chapter7;
import java.util.*;

public class ManagePoint {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		HashMap<String, Integer> info = new HashMap<String, Integer>();

		System.out.println("** 포인트 관리 프로그램입니다. **");

		while(true) {
			System.out.print("이름과 포인트 입력>>");
			String name = sc.next();
			if(name.equals("그만")) break;
			int point = sc.nextInt();

			if(info.containsKey(name)) {	//키가 존재하면 누적
				int value = info.get(name);
				value += point;
				info.put(name, value);
			}	//아니면 생성
			else info.put(name, point);
			
			Set<String> keys = info.keySet();
			Iterator<String> it = keys.iterator();

			while(it.hasNext()) {
				String key = it.next();
				int value = info.get(key);
				System.out.println("(" + key + ", " + value + ") ");
			}
		}
		sc.close();
	}
}

 

 

9. 다음 IStack 인터페이스가 있다.
interface IStack<T> {
	T pop();
	boolean push(T ob);
}
IStack<T> 인터페이스를 구현하는 MyStack<T> 클래스를 작성하라. 스택의 원소는 Vector<E>를 이용하여 저장하라. 

 

package chapter7;
import java.util.*;

interface IStack<T> {
	T pop();
	boolean push(T ob);
}

class MyStack<T> implements IStack<T>{
	ArrayList<T> l = null;
	public MyStack() {
		l = new ArrayList<T>();
	}
	public T pop() {
		if(l.size() == 0)
			return null;
		else {
			return l.remove(0);
		}
	}
	public boolean push(T ob) {
		l.add(0, ob);
		return true;
	}
}
public class StackManager {
	public static void main(String[] args) {
		IStack<Integer> stack = new MyStack<Integer>();
		for(int i = 0; i < 10; i++) stack.push(i);
		while(true) {
			Integer n = stack.pop();
			if(n == null) break;
			System.out.print(n + " ");
		}
	}
}

 

 

10. Vector<Shape>의 벡터를 이용하여 그래픽 편집기를 만들어보자. 본문 5.6절과 5.7절에서 사례로 든 추상 클래스 Shape과 Line, Rect, Circle 클래스 코드를 잘 완성하고 이를 활용하여 "삽입", "삭제", "모두 보기", "종료"의 4가지 그래픽 편집 기능을 가진 프로그램을 작성하라.

 

package chapter7;
import java.util.*;

abstract class Shape{
	public abstract void draw();
}

class Line extends Shape {
	String name ="line";
	public void draw() {
		System.out.println("Line");
	}
}
class Rect extends Shape {
	String name ="Rect";
	public void draw() {
		System.out.println("Rect");
	}
}
class Circle extends Shape {
	String name ="circle";
	public void draw() {
		System.out.println("Circle");
	}
}
public class GraphicEditor {
	Scanner sc = new Scanner(System.in);
	Vector<Shape> v = new Vector<Shape>();
	public void insert(int shape) {
		Shape s;
		switch(shape) {
		case 1:
			s = new Line(); v.add(s); break;
		case 2: 
			s = new Rect(); v.add(s); break;
		case 3:
			s = new Circle(); v.add(s); break;
		default:
			System.out.println("잘못된 입력입니다."); return;
		}
	}
	public void delete(int pos) {
		v.remove(pos - 1);
	}
	public void print() {
		for(int i = 0; i < v.size(); i++) {
			Shape s = v.get(i);
			s.draw();
		}
	}
	public void run() {
		System.out.println("그래픽 에디터 beauty를 실행합니다.");
		while(true) {
			System.out.print("삽입(1), 삭제(2), 모두 보기(3), 종료(4)>>");
			int n = sc.nextInt();
			switch(n) {
			case 1: 
				System.out.print("Line(1), Rect(2), circle(3)>>");
				int shape = sc.nextInt();
				insert(shape); break;
			case 2:
				System.out.print("삭제할 도형의 위치>>");
				int target = sc.nextInt();
				delete(target); break;
			case 3:
				print(); break;
			case 4:
				System.out.println("beauty을 종료합니다.");
				sc.close();
				return;
			}
		}
	}
	public static void main(String[] args) {
		GraphicEditor e = new GraphicEditor();
		e.run();		
	}
}

 

 

11. 나라와 수도 맞추기게임을 작성하라.

(1) 나라 이름(country)과 수도(capital)로 구성된 Nation 클래스를 작성하고 Vector<Nation> 컬렉션을 이용하여 프로그램을 작성하라.

(2) 이 프로그램을 HashMap<String, String>을 이용하여 작성하라. '키'는 나라 이름이고 '값'은 수도이다.

 

1)

package chapter7;
import java.util.*;

class Nation {
	private String country, capital;
	public Nation(String country, String capital) {
		this.country = country;
		this.capital = capital;
	}
	public String getCountry() {
		return country;
	}
	public String getCapital() {
		return capital;
	}
}

public class QuizVector {
	Scanner sc = new Scanner(System.in);
	Vector<Nation> v = new Vector<Nation>();
	
	public QuizVector() {
	v.add(new Nation("멕시코", "멕시코시티"));
	v.add(new Nation("스페인", "리스본"));
	v.add(new Nation("프랑스", "파리"));
	v.add(new Nation("영국", "런던"));
	v.add(new Nation("그리스", "아테네"));
	v.add(new Nation("독일", "베를린"));
	v.add(new Nation("일본", "동경"));
	v.add(new Nation("중국", "베이찡"));
	v.add(new Nation("러시아", "모스크바"));
	}
	
	private boolean contains(String country) {
		for(int i=0; i<v.size(); i++) {
			if(v.get(i).getCountry().equals(country)) { // 사용자가 입력한 나라가 이미 있다면
				return true;
			}
		}
		return false;
	}
	
	public void insert() {
		System.out.println("현재 " + v.size() + "개 나라와 수도가 입력되어 있습니다.");
		while(true) {
			System.out.print("나라와 수도 입력>>");
			String country = sc.next();
			if(country.equals("그만")) break;
			String capital = sc.next();
			
			if(contains(country)) { // 사용자가 입력한 나라가 이미 있다면
				System.out.println(country + "는 이미 있습니다!");
				continue;
			}
			
			v.add(new Nation(country, capital));	//벡터에 객체 추가
		}
	}
	
	public void play() {
		while(true) {
			// 나라 중에서 하나를 선택한다.
			int index = (int)(Math.random()*v.size()); // 랜덤한 위치 결정
			
			// 문제(나라)와 정답(수도)을 결정한다.
			Nation nation = v.get(index);
			String question = nation.getCountry();
			String answer = nation.getCapital();
			
			// 문제를 출력한다.
			System.out.print(question + "의 수도는? ");
			
			String capitalFromUser = sc.next(); // 사용자의 입력
			if(capitalFromUser.equals("그만")) {
				break;
			}
			if(capitalFromUser.equals(answer))
				System.out.println("정답!!");
			else
				System.out.println("아닙니다!!");				
		}	
	}
	
	public void run() {
		System.out.println("***수도 맞추기 게임을 시작합니다. ***");
		while(true) {
			System.out.print("입력:1, 퀴즈:2, 종료:3>>");
			int select = sc.nextInt();
			switch(select) {
			case 1:
				insert(); break;
			case 2:
				play(); break;
			case 3:
				sc.close();
				System.out.println("게임을 종료합니다.");
				return;
			}
		}
	}
	
	public static void main(String[] args) {
		QuizVector q = new QuizVector();
		q.run();
	}
}

 

2)

package chapter7;
import java.util.*;

public class QuizHashMap {
	Scanner sc = new Scanner(System.in);
	HashMap<String, String> v =  new HashMap<String, String>();
	
	public QuizHashMap() {
	v.put("멕시코", "멕시코시티");
	v.put("스페인", "리스본");
	v.put("프랑스", "파리");
	v.put("영국", "런던");
	v.put("그리스", "아테네");
	v.put("독일", "베를린");
	v.put("일본", "동경");
	v.put("중국", "베이찡");
	v.put("러시아", "모스크바");
	}
	
	public void insert() {
		System.out.println("현재 " + v.size() + "개 나라와 수도가 입력되어 있습니다.");
		while(true) {
			System.out.print("나라와 수도 입력>>");
			String country = sc.next();
			if(country.equals("그만")) break;
			String capital = sc.next();
			
			if(v.containsKey(country)) { // 사용자가 입력한 나라가 이미 있다면
				System.out.println(country + "는 이미 있습니다!");
				continue;
			}
			
			v.put(country, capital);	//벡터에 객체 추가
		}
	}
	
	public void play() {
		while(true) {
			Set<String> keys = v.keySet();
			Object [] array = (keys.toArray());
			int index = (int)(Math.random()*array.length); // 랜덤한 위치 결정
			
			// 문제(나라)와 정답(수도)을 결정한다.
			String question = (String)array[index];
			String answer = v.get(question);
			
			// 문제를 출력한다.
			System.out.print(question + "의 수도는? ");
			
			String capitalFromUser = sc.next(); // 사용자의 입력
			if(capitalFromUser.equals("그만")) {
				break;
			}
			if(capitalFromUser.equals(answer))
				System.out.println("정답!!");
			else
				System.out.println("아닙니다!!");				
		}	
	}
	
	public void run() {
		System.out.println("***수도 맞추기 게임을 시작합니다. ***");
		while(true) {
			System.out.print("입력:1, 퀴즈:2, 종료:3>>");
			int select = sc.nextInt();
			switch(select) {
			case 1:
				insert(); break;
			case 2:
				play(); break;
			case 3:
				sc.close();
				System.out.println("게임을 종료합니다.");
				return;
			}
		}
	}
	
	public static void main(String[] args) {
		QuizVector q = new QuizVector();
		q.run();
	}
}

 

 

12. Open Challenge를 수정하여 사용자가 단어를 삽입할 수 있도록 기능을 추가하라.

 

package chapter7;

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

class Word { // 영어 단어와 한글 단어를 쌍으로 가진 하나의 단어 표현
	private String english; // 영어 단어
	private String korean; // 영어 단어에 해당하는 한글 단어
	public Word(String english, String korean) {
		this.english = english;
		this.korean = korean;
	}
	public String getEnglish() { return english; }
	public String getKorean() { return korean; }
	
}
public class WordQuiz {
	Scanner sc = new Scanner(System.in);
	private String name; // 퀴즈 프로그램의 이름
	private Vector<Word> v;

	public WordQuiz(String name) {
		this.name = name;
		v = new Vector<Word>();
		v.add(new Word("love", "사랑"));
		v.add(new Word("animal", "동물"));
		v.add(new Word("emotion", "감정"));
		v.add(new Word("human", "인간"));
		v.add(new Word("stock", "주식"));
		v.add(new Word("trade", "거래"));
		v.add(new Word("society", "사회"));
		v.add(new Word("baby", "아기"));
		v.add(new Word("honey", "꿀"));
		v.add(new Word("dall", "인형"));
		v.add(new Word("bear", "곰"));
		v.add(new Word("picture", "사진"));
		v.add(new Word("painting", "그림"));
		v.add(new Word("fault", "오류"));
		v.add(new Word("example", "보기"));
		v.add(new Word("eye", "눈"));
		v.add(new Word("statue", "조각상"));
	}
	
	// ex[] 배열에 4개의 보기를 만든다. 보기는 현재 단어 벡터에 있는 단어를 랜덤하게 4개를 선택하고, 벡터에 대한 인덱스를
	// ex[] 배열에 저장한다.
	// answerIndex는 정답이 있는 벡터의 인덱스이므로, ex []에는 answerIndex 값이 들어가지 않도록 한다.
	// 그러므로 이 메소드가 리턴할 때는 answerIndex가 없는 ex[] 배열이 만들어지며, ex[] 배열에 대한 임의의 인덱스틀
	// 리턴한다. 이 메소드가 끝난 뒤 이 위치에 answerIndex를 심는다. 
	private int makeExample(int ex[], int answerIndex) {
		int n[] = {-1, -1, -1, -1}; // -1로 초기화
		int index;
		for(int i=0; i<n.length; i++) {
			do {
				index = (int)(Math.random()*v.size());
			} while(index == answerIndex || exists(n, index)); // 다시 시도
			n[i] = index;
		}

		for(int i=0; i<n.length; i++) ex[i] = n[i];
		return (int)(Math.random()*n.length); // ex[] 배열 내의 임의의 위치 리턴. 이곳에 정답을 심는다.
	}
	
	// 배열 n[]에 index의 값이 존재하면 true, 아니면 false 리턴
	private boolean exists(int n[], int index) {
		for(int i=0; i<n.length; i++) {
			if(n[i] == index)
				return true;
		}
		return false;
	}
	
	public void quiz() {
		System.out.println("\"" + name + "\"" + "의 단어 테스트를 시작합니다. -1을 입력하면 종료합니다.");
		System.out.println("현재 " + v.size() + "개의 단어가 들어 있습니다.");
		while(true) { 
			int answerIndex = (int)(Math.random()*v.size()); // 정답이 들어 있는 벡터 항목의 인덱스
			String eng = v.get(answerIndex).getEnglish(); // 문제로 주어질 영어 단어
			
			// 4개의 보기를 만들 벡터의 index 배열
			int example[] = new int [4];
			
			int answerLoc = makeExample(example, answerIndex); // 정답이 있는 보기 번호
			example[answerLoc] = answerIndex; // 보기에 정답 인덱스 저장

			// 문제를 출력합니다.
			System.out.println(eng + "?");
			for(int i=0; i<example.length; i++)
				System.out.print("(" + (i+1) + ")" + v.get(example[i]).getKorean() + " "); // 보기 출력
			
			System.out.print(":>"); // 프롬프트
			try {
				int in = sc.nextInt(); // 사용자의 정답 입력
				if(in == -1) {
					break; // 프로그램 종료
				}

				// 사용자가 1~4 사이의 정답 입력
				in--; // 1~4를 0~3의 인덱스로 바꿈
				if(in == answerLoc)
					System.out.println("Excellent !!");
				else
					System.out.println("No. !!");
			}
			catch(InputMismatchException e) {
				sc.next(); // 현재 스트림 버퍼에 입력되어 있는 입력을 읽어서 제거함
				System.out.println("숫자를 입력하세요 !!");
				// while 문으로 다시 반복
			}
		}
	}
	private boolean contains(String eng) {
		for(int i=0; i<v.size(); i++) {
			if(v.get(i).getEnglish().equals(eng)) { // 사용자가 입력한 단어가 이미 있다면
				return true;
			}
		}
		return false;
	}
	
	public void insert() {
		System.out.print("현재 " + v.size() + "개 단어가 입력되어 있습니다.");
		System.out.println("-1을 입력하면 테스트를 종료합니다.");
		while(true) {
			System.out.print("영어 한글 입력>>");
			String english = sc.next();
			if(english.equals("그만")) break;
			String capital = sc.next();
			
			if(contains(english)) { // 사용자가 입력한 단어가 이미 있다면
				System.out.println(english + "는 이미 있습니다!");
				continue;
			}
			
			v.add(new Word(english, capital));	//벡터에 객체 추가
		}
	}
	public void run() {
		System.out.println("****영어 단어 테스트 프로그램 \"명품영어\" 입니다. ****");
		while(true) {
			System.out.print("단어테스트:1, 단어 삽입:2, 종료:3>>");
			int select = sc.nextInt();
			switch(select) {
			case 1:
				quiz(); break;
			case 2:
				insert(); break;
			case 3:
				sc.close();
				System.out.println("게임을 종료합니다.");
				return;
			}
		}
	}
	public static void main(String[] args) {
		WordQuiz quiz = new WordQuiz("명품영어");
		quiz.run();
	}
}

 

 

13. 명령을 실행하는 소프트웨어를 작성하라. 명령은 다음과 같이 mov, add, sub, jn0, prt로 구성되며 mov sum 0은 sum 변수에 0을 삽입하고, add sum i는 sum 변수에 i 값을 더하며, sub n 1은 n 변수의 값을 1 감소시키고, jn0 n 3은 변수 n의 값이 0이 아니면 3번째 명령(실제 4번째 줄)으로 돌아가도록 처리하고, prt sum 0은 sum 변수의 값을 출력하고 프로그램을 종료한다. prt에서 마지막 0은 특별한 의미가 없다. go는 지금까지 입력한 프로그램을 처음부터 실행하도록 하는 지시어이다.

 

*출판사 제공 풀이와 동일

package chapter7;

import java.util.*;

class Instruction {
	private String line;
	private String opcode;
	private String operand [] = new String [2];
	public Instruction(String line) {
		this.line = line;
		line = line.toUpperCase(); // 대문자로 만들기
		StringTokenizer st = new StringTokenizer(line);
		// line이 "ADD S J"
		opcode = st.nextToken(); // 첫 토큰, 명령, "ADD"
		operand[0] = st.nextToken(); // "S"
		operand[1] = st.nextToken(); // "J"
	}
	
	public String getOpcode() {
		return opcode;
	}
	
	public String getOperand(int index) {
		if(index < 0 || index > 2)
			return null;
		return operand[index];
	}
	
	public String toString() {
		return "[" + line + "] ";
	}
}

public class Machine {
	private String name;
	private HashMap<String, Integer> memory = new HashMap<String, Integer>();
	private Vector<Instruction> program = new Vector<Instruction>();
	private Scanner scanner = new Scanner(System.in);
	
	public Machine(String name) {
		this.name = name;
	}
	
	public void readProgramIntoMemory() {
		while(true) {
			System.out.print(">> ");
			String line = scanner.nextLine();
			if(line.toUpperCase().equals("GO"))
				break;
			program.add(new Instruction(line));
		}
	}
	public void clearMemory() {
		program.removeAllElements(); // 벡터의 모든 요소 삭제
		memory.clear();
	}
	
	public void error(int pc, String msg) {
		System.out.print("프로그램 라인 " + (pc+1) + "에서 오류. " + msg);
	}
	
	public void execute() {
		int pc=0;
		while(true) {
			Instruction instruction = program.get(pc);
			pc++; // 미리 다음 명령의 주소로 설정
			switch(instruction.getOpcode()) {
				case "MOV" : mov(instruction); break;
				case "ADD" : add(instruction); break;				
				case "SUB" : sub(instruction); break;
				case "JN0" : 
					int newAddr = jn0(instruction);
					if(newAddr == -1) // no jump
						break; // break from switch
					else {
						pc = newAddr;
						break;
					}				
				case "PRT" : prt(instruction); return;
				default : 	error(instruction); return;
			}

			// printVariables(instruction); // 이 메소드를 실행하면 실행 중에 변하는 변수 모두 볼 수 있음
		}
	}
	
	private void error(Instruction instruction) {
		System.out.print("명령 오류! ");
		printVariables(instruction);
	}
	
	private void printVariables(Instruction instruction) {
		System.out.print(instruction+"\n");
		
		Set<String> s = memory.keySet();
		Iterator<String> it = s.iterator();
		while(it.hasNext()) {
			String variable = it.next();
			int value = memory.get(variable);
			System.out.print(variable + ":" + value + "\t");
		}
		System.out.println();
	}
	
	private void prt(Instruction instruction) { // 첫번째 피연산자 값을 출력하고 종료. 두번째 피연산자는 의미없음
		String first = instruction.getOperand(0);
		
		int n = getValue(first);
		printVariables(instruction); 
		System.out.println("출력할 결과는 " + n + ". 프로그램 실행 끝");
	}

	private int jn0(Instruction instruction) { // 첫번째 피연산자가 0이 아니면 두번째 피연산자의 주소로 점프
		String first = instruction.getOperand(0);
		String second = instruction.getOperand(1);
		
		int n = getValue(first);
		int m = getValue(second);
		if(n != 0) { // n이 0이 아니면
			return m; // 점프할 주소
		}
		else
			return -1; // 점프 없이 다음으로 진행
	}
	
	private void sub(Instruction instruction) {
		String first = instruction.getOperand(0);
		String second = instruction.getOperand(1);
		
		int n = getValue(first);
		int m = getValue(second);
		memory.put(first, n-m);
	}

	private void add(Instruction instruction) {
		String first = instruction.getOperand(0);
		String second = instruction.getOperand(1);
		
		int n = getValue(first);
		int m = getValue(second);
		memory.put(first, n+m);
	}
	
	private void mov(Instruction instruction) {
		String variable = instruction.getOperand(0); // 첫번째 변수
		String second = instruction.getOperand(1); // 두번
		
		int n = getValue(second);
		memory.put(variable, n); // 첫번째 변수에 값 저장
	}
	
	private int getValue(String opr) { // opr이 정수이면 수로 리턴. 변수명이면 변수명의 값 리턴.없는 변수이면 새로만들고 0리턴
		int n;
		try {
			n = Integer.parseInt(opr); // opr 피연산자가 정수인 경우
		}
		catch(NumberFormatException e) { // opr 피연산자가 변수인 경우
			Integer value = memory.get(opr); // 변수 값 알아내기
			if(value == null) { // opr 이름의 변수가 없다면
				memory.put(opr, 0); // opr의 값을 0으로 하여 새 변수 생성
				n = 0; // 초기 값 0
			}
			else {
				n = value; // opr 변수의 저장 값
			}
		}
		return n;
	}

	public void run() {
		System.out.println(name + "이 작동합니다. 프로그램을 입력해주세요. GO를 입력하면 작동합니다.");
		while(true) {
			readProgramIntoMemory(); // "GO" 가 입력될 때까지 읽기
			execute();
			clearMemory();
		}
	}
	
	public static void main(String[] args) {
		Machine m = new Machine("수퍼컴");
		m.run();
	}
}