문제풀이/일일연습문제

일일문제 : 7번째- 221221 [12-3-수] - 객체지향 위인전

Mo_bi!e 2022. 12. 21. 13:17

[12번]

1. 문제설명

 다음 각 문항에 답을 하시오.

 

// 1. 다음 그림을 보고 Room 클래스와 Student 클래스를 작성하시오.

 

 

// 2. 다음 코드는 App 클래스의 main 메소드 코드이다.

 

Room room = new Room();

room.load(“res/students.csv”);

room.shuffle();

room.print();

room.sort();

room.print();



res/students.csv 파일내용을 읽어서  Room의 students 배열을 채우는 load() 코드를 작성하시오. students.csv 파일 내용은 다음과 같다.

 

id,name

1,홍길동

2,강감찬

3,세종대왕

4,이순신

5,이방원

6,이성계

7,아이유

8,유재석

9,강호동

10,김종국

 

// 3. students 배열을 랜덤하게 뒤섞는 shuffle() 메소드를 구현하시오.

// 섞인 예는 다음과 같다.

 

6,이성계

3,세종대왕

2,강감찬

4,이순신

7,아이유

8,유재석

5,이방원

9,강호동

10,김종국

1,홍길동

 

// 4. Room과 Student 클래스의 print() 메소드를 구현하시오.



// 5. Room 클래스의 sort() 메소드를 구현하시오.

2. 나의 해답

<App>

package T221221;

import java.io.IOException;

public class App {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub

		Room room = new Room();
		room.load("res/students.csv");
		room.shuffle();
		room.print();
		room.sort();
		room.print();
	}

}

<Room>

package T221221;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Random;
import java.util.Scanner;

public class Room {
	
	Student[] student;

	public void load(String src) throws IOException {
		
		//동적으로 배열 사이즈 정해주기
		{
			FileInputStream fis = new FileInputStream(src);
			Scanner scanner = new Scanner(fis);
			
			int number = 0;	
			
			
			while(scanner.hasNext()) {
				String id = scanner.nextLine();
				System.out.println(id);
				
				if(id.equals("id,name"))
					continue;
				
				number++;
			}
			
			System.out.printf("객체의 수는 %d개 \n ", number);
			student = new Student[number];
			System.out.printf("%d개 객체 생성 완료 \n", student.length);
			
			scanner.close();
			fis.close();
		}
		
		
		{
		//불러오기
		FileInputStream fis = new FileInputStream(src);
		Scanner scanner = new Scanner(fis);
		
		String [] token = new String[2];
		
		for(int i = 0 ; i < student.length; i++) {
			String nameLine= scanner.nextLine();
			
			if(nameLine.equals("id,name")) {
				i -= 1; //i 다시 조절해주기
				continue;
			}
			
			System.out.println(nameLine);
			
			token = nameLine.split(",");
			//token 사람마다 id와 이름 단위로 끊기
			student[i] = new Student(); //메모리할당
			
			//id와 name 분리 후 대입하기
			int id = Integer.parseInt(token[0]);
			student[i].setId(id); 
			student[i].setName(token[1]);
		}
		
		System.out.println("★set 완료");
		
		scanner.close();
		fis.close();
		}
		
	}

	
	
	public void shuffle() {
		// TODO Auto-generated method stub
		
		Random rand = new Random();
		
		for(int i = 0 ; i < 50 ; i++){
		
			//두가지 방식 존재
		int random = (int)(Math.random() * 10) ;
		int random2 = rand.nextInt(10); //0부터 9까지 10개
		
		Student tmp;
		
		//참조변수만 바꿈
		tmp = student[random];
		student[random] = student[random2];
		student[random2] = tmp;
		
		}
		
		System.out.println("\n★섞기 완료");
		
		
		
	}


	public void sort() {
		
		Student tmp;
		
		for(int j = 0 ; j < student.length -1 -1 ; j++)
			for(int i = 0 ; i < student.length -1 - j ; i++) {
				if(student[i].getId() > student[i+1].getId()) {
					tmp = student[i];
					student[i] = student[i+1];
					student[i+1] = tmp;
				}
			}
		System.out.println("\n★정렬완료");
	}
	
	
	public void print() {
		
		for(int i = 0 ; i < student.length; i++)
			student[i].print();
		
		System.out.println("★출력완료");
	}
	
	
}

<Student>

package T221221;

import java.io.PrintStream;

public class Student {

	private int id;
	private String name;
	
	
	//id
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}


	//Name
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}


	public void print() {
			System.out.printf("%d %s\n", this.getId(), this.getName());
	}

}

 

 

3. 정답 코드

 

 

4. 보충 및 회고 

(1) 보충

1) usecase 에 대한 기호 이해

 

2) 좀 더, 선 수도코드 지향적 사고

nextLine 과 spilit 간의 관계에서 하드코딩을 시도 함

 

3) eauals 에 대한이해

 a.eauals(b)

여기서 a와 b가 같으면 true를 반환해주는 함수이다.

 

 

(2) 회고 : 문제풀이과정에서 어떻게 접근하려고했는지 (접근방법) + 어려움이 있었는데 해결했다.

 

1) 문제조건에서 배열사이즈가 명확히 정해져있지 않음.

객체배열 사이즈가 10개라고 정해져있지 않다.

이런경우 실제 배열사이즈가 몇개인지 알아보는것이좋다.

파일을 불러오면서 읽어 오는 과정에서 number를 증가연산해주면된다.

 

2) csv첫번째 줄에 [id, name] 부분은 적용안되게끔 하는것이 어려웠다

equals() 함수를 처음으로 이용해보았다.

 

ex) a.eauals(b)

여기서 a와 b가 같으면 true를 반환해주는 함수이다.

그래서 nextLine 에 의한 문자열에서 동일한것이 있는지 찾게끔 해서 할수있다.

그리고 해당 한 문장이 있으면 반복문의 continue를 이용해서 다시 처음으로 가게끔할수있다.

 

2-1) 배열사이즈용 외, 객체배열에 값을 저장할 때 인덱스가 꼬이는 문제(특히 for문 경우)가 있다.

continue 문을 쓰더라도 i는 0이 아니라 1부터 시작되기때문이다.

이런 경우에는 continue 쓰기전에 i -=1 을 써서 값을 줄여주는것이 중요하다.

 

3) load 메소드 구현에 문제 

load를 구현할 때 Student 객체는 배열이고, 불러온 파일은 newLine단위이다.

 

이런경우 newLine 함수는 불러온 파일을 한줄만 읽을 수 있다.

그렇기 때문에 newLine함수는 반복문 안에 넣어주어야하는데, 파일의 형태를 생각하지못해서 아쉽다.

 

또한 spilt 함수는 newLine전까지만 읽어올수있다.

이런 경우 split 단위는 단 두개만 나온다

 

결국 load메소드를 구현할 때 예전부터 이용했던 함수 원리에 대한 이해없이 이용했다결국 이 과정에서 다소 어려움이 있었는데 아쉽다.

 

4) Shuffle 메소드 구현 방식섞기 위해서 난수 출력하는 방식을 두가지가 있다는 것을 다시 알게되었다Math 와 Random 두가지이다. Math를 이용할때 정수형으로 형변환을 손쉽게 할수있어서 뿌듯하다Random은 수업시간에 알려주었는데 이것을 바로 생각하지 못해서 아쉽다.

 

5) 두 클래스에 모두 print() 있을 경우print()메소드는 메인메소드에서 호출을 한다.두클래스에 모두 있는데, 중간에 Room 클래스에서 매개하게끔 하는것이 중요하다여기서 다소 헷갈리면서 뿌듯한점은 Student 클래스에서 this로 인스턴스를 특정한 것을 바로 생각해낸것이 뿌듯하다.

 

6) 순서를 바꿀때 얕은복사를 이용한것이 뿌듯하다. (다만 이 개념 유의하기)

깊은 ,얕은 개념을 알아서 시도할수 있어서 좋았다.


<오전 문제 리뷰>

생성자를 오버로드 하더라도 기본생성자 만들자!

데이터 담는 클래스의 객체이름은 -s를 붙이

 

인덱스 사용하는 반복문은 for문을 사용하자

 

student.length 는 채워진 배열만을 가정해서 문제있다 (값의 크기와 공간의 차이간의 gap일때)

 

print() 값의 변수를 출력해야지 배열의 변수 출력바람직 X

 

sort에서 id간 비교를 할 때 바로 비교하지말고 변수를 담아서 비교하는 것이 바람직하다.

변수를 쓰는것은 메모리를 먹으나, 내가 이해하기가 더 쉽다.