/****************************************************************************** * 문제 4-2 ******************************************************************************/ // 새로운 프로젝트와 Main.java 소스파일을 만든 후 [문제 4-1]에서 작성한 소스코드를 복사해서 삽입하라. // [문제 4-2] 실행 결과를 참고하여 아래 코드를 작성하라. // 1) 기존의 main() 함수 내에 있던 String[] name, int[] tall 변수를 Manager 클래스의 // static private 멤버로 옮겨라. // 2) 아래 main() 함수에서 호출하는 Manager.makeManager(in) 문장을 참조하여 Manager 클래스에 // 해당 함수를 구현하라. 기존 [문제 4-1]의 main 함수에 있던 manager 객체 // 생성하는 코드들(while 문장 앞까지의 코드)를 makeManager(in) 함수로 옮기면 된다. // 그리고 생성된 manager 객체를 리턴하면 된다. // 3) Manager 객체는 항상 makeManager(in) 함수를 사용하여 생성하고 사용자가 직접 // new Manager(3) 형태로 호출하여 객체를 생성할 수 없게 하라. // 4) 기존 main() 함수를 아래 main() 함수로 교체하라. // 5) 메뉴 항목 "4.FindStudent2"를 선택할 경우 manager.findStudent(pname, tall)가 호출된다. // 이 함수를 구현하라. 이 함수는 Manager가 관리하는 학생 중에 입력된 이름과 키가 // 각각 pname과 tall과 동일한 학생을 찾아 출력한다. 찾지 못한 경우 적절한 에러 메시지를 출력한다.
public class Main
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
Manager manager = Manager.makeManager(in);
// manager = new Manager(3);
// 위 문장의 주석을 제거하면 Manager 생성자 접근할 수 없다는 에러가 발생하여야 한다.
while(true) {
System.out.print("\n0.Exit 1.DisplayAll 2.CalculateMean\n");
System.out.print("3.FindStudent 4.FindStudent2 5.MakeManager >> ");
int input = in.nextInt();
if (input == 0)
break;
switch (input) {
case 1: manager.displayAll();
break;
case 2: manager.calculateMean();
break;
case 3: System.out.print("name? ");
String pname = in.next();
manager.findStudent(pname);
break;
case 4: System.out.print("name, tall? ");
pname = in.next();
int tall = in.nextInt();
manager.findStudent(pname, tall);
break;
case 5: manager = Manager.makeManager(in);
break;
}
}
in.close();
}
}
실행결과 예시
===============================================================================
== [문제 4-2] 실행 결과
===============================================================================
input continuously 6 indices(index) of array: 0 1 2 3 4 5 // 사용자 입력: 0 ~ 5 숫자를 임의의 순서로 입력
0.Exit 1.DisplayAll 2.CalculateMean
3.FindStudent 4.FindStudent2 5.MakeManager >> 1
name tall difference
bob 172 0.00
john 183 0.00
alice 168 0.00
nana 161 0.00
tom 171 0.00
sandy 172 0.00
0.Exit 1.DisplayAll 2.CalculateMean
3.FindStudent 4.FindStudent2 5.MakeManager >> 2
tall mean: 171.17
name tall difference
bob 172 0.83
john 183 11.83
alice 168 -3.17
nana 161 -10.17
tom 171 -0.17
sandy 172 0.83
0.Exit 1.DisplayAll 2.CalculateMean
3.FindStudent 4.FindStudent2 5.MakeManager >> 5
input continuously 6 indices(index) of array: 5 4 3 2 1 0 // 사용자 입력: 0 ~ 5 숫자를 임의의 순서로 입력
0.Exit 1.DisplayAll 2.CalculateMean
3.FindStudent 4.FindStudent2 5.MakeManager >> 1 // 새로운 manager 객체가 생성되었고, 배열에 들어간 객체 순서도 다름
name tall difference
sandy 172 0.00
tom 171 0.00
nana 161 0.00
alice 168 0.00
john 183 0.00
bob 172 0.00
0.Exit 1.DisplayAll 2.CalculateMean
3.FindStudent 4.FindStudent2 5.MakeManager >> 2
tall mean: 171.17
name tall difference
sandy 172 0.83
tom 171 -0.17
nana 161 -10.17
alice 168 -3.17
john 183 11.83
bob 172 0.83
0.Exit 1.DisplayAll 2.CalculateMean
3.FindStudent 4.FindStudent2 5.MakeManager >> 4
name, tall? nana 161
nana 161 -10.17
0.Exit 1.DisplayAll 2.CalculateMean
3.FindStudent 4.FindStudent2 5.MakeManager >> 4
name, tall? nana 160
nana 160: not found.
0.Exit 1.DisplayAll 2.CalculateMean
3.FindStudent 4.FindStudent2 5.MakeManager >> 4
name, tall? NANA 161
NANA 161: not found.
0.Exit 1.DisplayAll 2.CalculateMean
3.FindStudent 4.FindStudent2 5.MakeManager >> 4
name, tall? bob 171
bob 171: not found.
0.Exit 1.DisplayAll 2.CalculateMean
3.FindStudent 4.FindStudent2 5.MakeManager >> 4
name, tall? bob 172
bob 172 0.83
0.Exit 1.DisplayAll 2.CalculateMean
3.FindStudent 4.FindStudent2 5.MakeManager >> 0
2. 정답코드
import java.util.Scanner;
class Student {
// 아래 name, tall, diff는 반드시 private로 하라.
private String name;
private int tall;
private double diff;
public Student(String name, int tall){
this.name = name;
this.tall = tall;
}
public void printStudent() {
System.out.printf("%s\t%d\t%6.2f\n", name, tall, diff);
}
// 필요한 경우 멤버 값을 설정하고 구해오는 메소드(함수)를 만들어 멤버에 접근하라.
public int getTall(){
return this.tall;
}
public void setDiff(double diff){
this.diff = diff;
}
public String getName(){
return this.name;
}
}
// 필요한 메소드(함수)를 구현하라.
class Manager {
private static String[] name = {"bob", "john", "alice", "nana", "tom", "sandy"};
private static int[] tall = {172, 183, 168, 161, 171, 172};
private int curIndex;
private Student[] students;
private Manager() {}
private Manager(int length){
this.curIndex = 0;
students = new Student[length];
}
public static Manager makeManager(Scanner in) {
Manager manager = new Manager(Manager.name.length);
System.out.print("input continuously 6 indices(index) of array: ");
// 0 ~ 5 사이의 서로 다른 6개의 숫자(임의의 순서)들을 연속적으로 입력 받으면서
// 학생 객체를 생성한 후 manager에 등록한다.
for(int i = 0; i < Manager.name.length; i++) {
int j = in.nextInt();
// manager 객체의 append 메소드를 실행하여 학생 객체 등록
// append()는 manager내의 학생 객체 배열에 순서적으로 삽입한다.
manager.append(new Student(name[j], tall[j]));
}
return manager;
}
public void displayAll(){
System.out.printf("name\ttall\tdifference\n");
for(int i=0; i<students.length; i++){
this.students[i].printStudent();
}
}
public void calculateMean(){
double total = 0;
for(int i=0; i<students.length; i++){ //total 구하기
total += this.students[i].getTall();
}
total /= this.students.length;
for(int i=0; i<students.length; i++){ //diff 구하기
this.students[i].setDiff(this.students[i].getTall() - total);
}
System.out.printf("tall mean:%.2f\n\n",total);
this.displayAll();
}
public void append(Student s){
students[curIndex++] = s;
}
public void findStudent(String name){
boolean findFlag = true;
for(int i=0; i<students.length; i++){
if(students[i].getName().equals(name)){
findFlag = false;
students[i].printStudent();
}
}
if(findFlag){
System.out.println(name+": not found.");
}
}
public void findStudent(String name, int tall) {
boolean findFlag = true;
for(int i=0; i<students.length; i++){
if(students[i].getName().equals(name) && students[i].getTall()==tall){
findFlag = false;
students[i].printStudent();
}
}
if(findFlag){
System.out.println(name+": not found.");
}
}
}
public class Main {
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
Manager manager = Manager.makeManager(in);
// manager = new Manager(3);
// 위 문장의 주석을 제거하면 Manager 생성자 접근할 수 없다는 에러가 발생하여야 한다.
while(true) {
System.out.print("\n0.Exit 1.DisplayAll 2.CalculateMean\n");
System.out.print("3.FindStudent 4.FindStudent2 5.MakeManager >> ");
int input = in.nextInt();
if (input == 0)
break;
switch (input) {
case 1: manager.displayAll();
break;
case 2: manager.calculateMean();
break;
case 3: System.out.print("name? ");
String pname = in.next();
manager.findStudent(pname);
break;
case 4: System.out.print("name, tall? ");
pname = in.next();
int tall = in.nextInt();
manager.findStudent(pname, tall);
break;
case 5: manager = Manager.makeManager(in);
break;
}
}
in.close();
}
}
3. 대충 풀이
1) 기존의 main() 함수 내에 있던 String[] name, int[] tall 변수를 Manager 클래스의 static private 멤버로 옮겨라.
이건 너무 쉬우니까 패스...
2) 아래 main() 함수에서 호출하는 Manager.makeManager(in) 문장을 참조하여 Manager 클래스에 해당 함수를 구현하라. 기존 [문제 4-1]의 main 함수에 있던 manager 객체 생성하는 코드들(while 문장 앞까지의 코드)를 makeManager(in) 함수로 옮기면 된다. 그리고 생성된 manager 객체를 리턴하면 된다.
public static Manager makeManager(Scanner in) {
Manager manager = new Manager(Manager.name.length);
System.out.print("input continuously 6 indices(index) of array: ");
// 0 ~ 5 사이의 서로 다른 6개의 숫자(임의의 순서)들을 연속적으로 입력 받으면서
// 학생 객체를 생성한 후 manager에 등록한다.
for(int i = 0; i < Manager.name.length; i++) {
int j = in.nextInt();
// manager 객체의 append 메소드를 실행하여 학생 객체 등록
// append()는 manager내의 학생 객체 배열에 순서적으로 삽입한다.
manager.append(new Student(name[j], tall[j]));
}
return manager;
}
Manager.makeManager로 호출하였으므로 해당 메소드는 static 이어야하므로 static으로 선언해준다.
① Manager 객체를 생성한다.
② 생성된 Manager 객체에 append 메소드를 통해 학생 정보를 넣어서 학생객체 배열을 관리할 수 있도록 해준다.
③ 설정이 끝난 Manager 객체를 반환해준다.
3) Manager 객체는 항상 makeManager(in) 함수를 사용하여 생성하고 사용자가 직접 new Manager(3) 형태로 호출하여 객체를 생성할 수 없게 하라.
① 사용자가 직접 new 키워드를 사용하여 객체를 생성하지 못하도록 생성자를 private로 선언해준다.
4) 기존 main() 함수를 아래 main() 함수로 교체하라. (너무 쉬우니 패스)
5) 메뉴 항목 "4.FindStudent2"를 선택할 경우 manager.findStudent(pname, tall)가 호출된다.이 함수를 구현하라. 이 함수는 Manager가 관리하는 학생 중에 입력된 이름과 키가 각각 pname과 tall과 동일한 학생을 찾아 출력한다. 찾지 못한 경우 적절한 에러 메시지를 출력한다.
기본적으로 기존 findStudent 메소드와 같다.
① 기존의 findStudent이다.
② 새로 생성된 findStudent이다. Main 메소드를 보면 3번 또는 4번 모두 manager.findStudent를 호출하고 있다. 이는 바로 메소드 오버로딩을 이용하라는 의미이다. (같은 메소드 이름이지만 메소드 시그니처를 다르게 하여 서로 구분하는 것) 매개변수 갯수를 다르게 하여 메소드 오버라이딩을 구현하였다.
③ 새로 생성된 findStudent 로직 중 기존과 다른 점은 그저 키까지 같이 비교하는 부분이다. AND(&&) 조건을 이용하여 구현하면 끝~
/****************************************************************************** * 문제 4-1 ******************************************************************************/ // 새로운 프로젝트를 만든 후 새로운 클래스 Main를 만들어 Main.java 소스파일을 만들어라. // 그런 후 아래 main 메소드를 복사해 소스파일에 넣어라.
// 클래스 정의, 생성자, 접근자, 객체배열 및 정적클래스와 관련된 문제이다.
// 아래 프로그램은 Student, Manager, Main으로 구성된다.
//
// 프로그램의 실행결과를 먼저 확인하라.
// 먼저 0 ~ 5 사이의 서로 다른 6개의 숫자를 임의의 순서로 연속적으로 입력 받는다.
// 이는 Manager에 추가할 학생들의 인덱스 순서이다.
// 그런 후 5명의 학생 객체를 생성하여 Manager에 추가한다.
// Manager는 5명의 학생 객체를 객체 배열에 저장하여 관리한다.
//
// Student, Manager 클래스의 멤버는 필요에 따라 추가해야 한다.
//
// 메뉴의 각 항목의 기능은 다음과 같으며, 이 순서로 구현하라.
// 1.DisplayAll: Manager가 관리하는 모든 학생 정보를 출력해야 한다.
// Student의 printStudent()를 활용하라. 오타를 줄이기 위해 아래 문장도 사용하라.
//System.out.printf("name\ttall\tdifference\n");
//
// 2.CalculateMean: Manager가 관리하는 모든 학생들의 키의 평균 값을 구해서 출력하고
// 이때 오타를 줄이기 위해 아래 문장을 사용하라.
//System.out.printf("tall mean: %.2f\n\n", mean);
// 각 학생의 키와 평균과의 차이 값을 각 학생 객체의 diff 멤버에 저장하라. (키가 평균보다 작으면 음수 값이 된다.)
// 그리고 학생 전체를 다시 디스플레이하라.
//
// 3.FindStudent: Manager가 관리하는 학생 중에 입력된 이름과 동일한 이름을 가진 학생을 찾아 출력한다.
// 찾지 못한 경우 아래의 에러 메시지를 출력한다.
//System.out.println(name+": not found.");
//
//=============================================================================
2. 전체코드
class Student {
// 아래 name, tall, diff는 반드시 private로 하라.
private String name;
private int tall;
private double diff;
public Student(String name, int tall){
this.name = name;
this.tall = tall;
}
public void printStudent() {
System.out.printf("%s\t%d\t%6.2f\n", name, tall, diff);
}
// 필요한 경우 멤버 값을 설정하고 구해오는 메소드(함수)를 만들어 멤버에 접근하라.
public int getTall(){
return this.tall;
}
public void setDiff(double diff){
this.diff = diff;
}
public String getName(){
return this.name;
}
}
// 필요한 메소드(함수)를 구현하라.
class Manager {
private int curIndex;
private Student[] students;
public Manager(int length){
this.curIndex = 0;
students = new Student[length];
}
public void displayAll(){
System.out.printf("name\ttall\tdifference\n");
for(int i=0; i<students.length; i++){
this.students[i].printStudent();
}
}
public void calculateMean(){
double total = 0;
for(int i=0; i<students.length; i++){ //total 구하기
total += this.students[i].getTall();
}
total /= this.students.length;
for(int i=0; i<students.length; i++){ //diff 구하기
this.students[i].setDiff(this.students[i].getTall() - total);
}
System.out.printf("tall mean:%.2f\n\n",total);
this.displayAll();
}
public void append(Student s){
students[curIndex++] = s;
}
public void findStudent(String name){
boolean findFlag = true;
for(int i=0; i<students.length; i++){
if(students[i].getName().equals(name)){
findFlag = false;
students[i].printStudent();
}
}
if(findFlag){
System.out.println(name+": not found.");
}
}
}
public class Main {
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
String[] name = {"bob", "john", "alice", "nana", "tom", "sandy"};
int[] tall = {172, 183, 168, 161, 171, 172};
// Manager 클래스의 객체변수 manager 선언 및 객체 생성
// name.length는 manager내에 생성될 학생배열의 길이임
Manager manager = new Manager(name.length);
System.out.print("input continuously 6 indices(index) of array: ");
// 0 ~ 5 사이의 서로 다른 6개의 숫자(임의의 순서)들을 연속적으로 입력 받으면서
// 학생 객체를 생성한 후 manager에 등록한다.
for(int i = 0; i < name.length; i++) {
int j = in.nextInt();
// manager 객체의 append 메소드를 실행하여 학생 객체 등록
// append()는 manager내의 학생 객체 배열에 순서적으로 삽입한다.
manager.append(new Student(name[j], tall[j]));
}
while(true) {
System.out.print("\n0.Exit 1.DisplayAll 2.CalculateMean 3.FindStudent >> ");
int input = in.nextInt();
if (input == 0)
break;
switch (input) {
case 1: manager.displayAll();
break;
case 2: manager.calculateMean();
break;
case 3: System.out.print("name? ");
String pname = in.next();
manager.findStudent(pname);
break;
}
}
in.close();
}
}
/****************************************************************************** * 문제 3-2 ******************************************************************************/ // 새로운 프로젝트와 Main.java 소스파일을 만든 후 [문제 3-1]에서 작성한 소스코드를 복사해서 삽입하라. // [문제 3-2] 실행 결과를 참고하여 아래 코드를 완성하라.
public class Main { public static int[][] makeArray(Scanner s) { 기존 함수를 다음과 같이 수정하라. 출력 결과를 참고하여 비정방형 배열 arr[][]을 생성한 후 해당 배열의 각 원소를 출력 결과처럼 초기화한 후 배열을 리턴한다. }
public static void printArray(int arr[][]) { 기존 코드와 동일 }
public static void main(String[] args) { 기존 코드와 동일함 } }
해당 문제는 1번 문제에서 만들었던 정방형 배열을 비정방형으로 바꾸는 꽤나 쉬운 문제였다.
2. 전체코드
import java.util.*;
class Main {
public static int[][] makeArray(Scanner s) {
System.out.print("array size? ");
int length = s.nextInt();
int arr[][] = new int[length][];
for(int i=0; i<length; i++){
arr[i] = new int[length - i]; //비정방형 배열 생성
int colLength = arr[i].length;
int value = i; //행마다 시작값이 바뀌게 설정.
for(int j=0; j<colLength; j++){
arr[i][j] = value++;
}
}
return arr;
}
public static void printArray(int arr[][]) {
//출력 결과를 참고하여 2차원 배열 arr[][]의 모든 원소들을 출력한다.
for(int i=0; i<arr.length; i++){
System.out.print("arr["+i+"] ");
for(int j =0; j < arr[i].length; j++){
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int arr[][];
while(true){ // 아래 과정을 계속 반복 수행한다.
arr = makeArray(scanner);
printArray(arr);
System.out.print("continue? ");
String str = scanner.next();
System.out.println();
//입력된 단어가 "yes"이면 계속 반복 수행하고 "yes"가 아니면 여기서 반복을 중단한다.
if(!str.equals("yes")) break;
}
scanner.close();
System.out.println("Done.");
}
}
3. 대충 이해하기
3-1번 문제와 비교하여 makeArray 메소드만 바뀌었고, 해당 부분도 정방형 배열에서 비정방형 배열로 바뀐 점이 핵심이다.
3-1. 각 행의 시작값 구하기
비정방형 배열에서 각 행의 시작값을 보면 각 행과 똑같은 것을 볼 수 있다.
0행은 0부터 시작
1행은 1부터 시작
2행은 2부터 시작
즉 코드로는 int value = 각 행의 index; 로 나타낼 수 있었다.
3-2. 각 행의 길이 구하기
각 행의 길이는 배열의 사이즈부터 시작해서 각 행을 반복할 수록 1씩 줄어드는 것을 볼 수 있었다.
코드로 나타내면 다음과 같다.
for(int i=0; i<length; i++){ //행을 반복하는 FOR문 arr[i] = new int[length - i]; //비정방형 배열 생성 (i가 커질수록 점점 작아진다.)
/****************************************************************************** * 문제 3-3 ******************************************************************************/ // 새로운 프로젝트와 Main.java 소스파일을 만든 후 [문제 3-2]에서 작성한 소스코드를 복사해서 삽입하라. // [문제 3-3] 실행 결과를 참고하여 아래 코드를 완성하라.
public class Main { public static int[][] makeArray(Scanner s) { 기존 코드와 동일 }
public static void printArray(int arr[][]) { 기존 코드와 동일 }
public static void printArrayElement(Scanner s, int arr[][]) { int r = 0, c = 0; "dividen? " 와 "divisor? " 를 출력하고 분자와 분모를 각각 입력 받는다. 분자를 분모로 나눈 몫을 행 변수 r에 저장하고 분자를 분모로 나눈 나머지를 열 변수 c에 저장 arr[r][c] 원소를 출력결과처럼 적절히 출력하고 리턴 위 과정을 처리하는 도중 예외가 발생할 경우 출력결과처럼 에러 원인을 출력하고 리턴 }
public static void main(String[] args) { Scanner scanner = 스캐너 객체 생성; int arr[][];
html, body{
height: 100%;
}
.wrap{
height: 100%;
min-width: 800px;
text-align: center;
}
.header{
height: 100px;
position: fixed;
background-color: aqua;
top: 0; left: 0; right: 0;
}
.container{
/* height를 %로 지정하기 위해서는 부모요소로 부터 높이값을 상속받아야한다. */
min-height: 100%;
margin: 0 auto;
margin-top: -100px;
padding-top: 200px; /* padding으로 해야 border-box를 사용하여 원하는 레이아웃을 만들 수 있다. */
box-sizing: border-box;
}
.content{
margin: 0 auto;
max-width: 1200px;
height: 300px;
background-color: brown;
}
.footer{
height: 100px;
background-color: blue;
}
CSS구조
레이아웃
※ reset.css 적용시켜줘야 된다!!
이제 하나하나 대충대충 이해한걸 뜯어보자.
3. 정리
3-1. 전체적인 레이아웃
※ 주의해야할 점!!!
주의해야할 점은 container 영역이 사실 header 영역에서 부터 footer 위까지 쭉 이어져 있다는 것이다. 이는 header가 fixed로 되면서 고정영역으로 되어있기 때문이다.
3-2. header
여기에서 중요한 점은 position을 fixed로 설정했다는 것이다.
고정 레이아웃은 상단(header)과 하단(footer) 또는 그 두 영역이 모두 컨텐츠의 높이나 내용에 상관없이 항상 노출 되도록 하는 레이아웃 이므로 fixed가 가장 중요하다고 생각한다.
3-3. container
# header fixed 문제 해결
고정 레이아웃을 공부할 때 가장 감명깊었던것이 container 부분이었다. 그 이유가 header가 fixed가 되면서 container 부분이 header 아래로 들어가버리는 현상을 해결해야했기 때문인데 단순히 margin-top: 100px;(header의 높이가 100px이니까 그만큼 내려주는 것) 을 하면 되는 줄 알았는데, 훨씬 좋은 방법 이 있었다.
[해결방법]
1. 오히려 margin-top : -100px; 을 해준다. (margin은 -를 하면 반대로 움직인다고 생각)
2. padding-top: 200px;
container의 height가 200px; 만큼 더 커진 이유가 중요하다.
예를 들면 해당 예시에서의 container 크기는 969px이다. (html 태그의 height 크기 자체가 969px이고, container는 min-height: 100%; 이기 때문에 부모의 height를 100% 상속받는다.)
하지만 padding-top:200px; 을 하면서 container의 크기가 200px 늘어나버려 1169px; 가 되어버린것.
그것을 해결하기 위해 box-sizing: border-box; 를 해준다.
이는 padding 값과 border 값도 포함하여 요소의 height를 지정해주는 속성값이다.