1. 년도와 월을 입력받아서 달력 출력하기
2010년 5월 달력을 출력할 수 있도록 코딩을 한 뒤 반복문을 이용하여 원하는 달력을 출력할 수 있는 코드를 작성하기
달력을 그리기 위해서는 아래와 같은 정보가 필요하다.
1. 달력 그리기(생성)
ㄱ. 해당 년도와 월의 1일은 무슨 요일? 2010년 5월 1일은 토요일
1) 총날짜수 구하기 : 1년1월1일 ~ 2010년 5월 1일까지 계산
2) 총날짜수 % 7 : 0(일) 1(월) 2(화) 3(수) 4(목) 5(금) 6(토)
ㄴ. 해당 년도와 월의 마지막 날짜는? 2010년 5월은 31일(월)
1) 28일 - 2월(평년)
2) 29일 - 2월(윤년)
3) 30일 - 4월, 6월, 9월, 11월
4) 31일 - 1월, 3월, 5월, 7월, 8월, 10월, 12월
먼저 년도(year)와 월(month)의 값을 넣을 변수 선언한 다음 입력받은 매개변수가 2개가 아닐 때 매개변수가 필요하다는 메시지를 출력하는 코딩을 한다. Run As - Run Configurations 을 이용하여 매개변수 값을 넣을 수 있도록 args 배열 0번 째 인덱스와 1번 째 인덱스를 year과 month 변수에 넣도록 코딩을 한 후 Run As - Run Configurations 을 이용하여 매개변수 값으로 2010, 5를 입력하여 Apply 후 Run을 하여 출력이 잘되는지 확인할 수 있도록 System.out.printf로 확인을 하는 작업을 먼저 한다.
main() 메서드 안에 코드 작성이 완료되었다면 이제 차근차근 4개의 메서드를 작성해보자!
1) 총날짜수 계산하기 - getTotalDays
2) 총날짜수 % 7 => 요일에 해당되는 정수값 구하기 - getDayOfWeek
3) 해당 월의 마지막 날짜 가져오기 - getLastDay
4) 달력 출력하기 - printCalender
1-1. 총날짜수 계산하기
private static int getTotalDays(int year, int month, int date) {
int totalDays = 0;
// 1) 구하고자하는 이전년도 (year(2010)-1 == 2009)의 총날짜수
// 1년 365일 평년
// 2년 365일 평년
// 3년 365일 평년
// 4년 366일 윤년
// [더 간략하게 윤년구하기] ***
totalDays = (year-1)*365 + (year-1)/4 - (year-1)/100 + (year-1)/400;
// (year-1)*365 : 윤년 계산하는 거 없이 모든 년도를 365로 계산
// (year-1)/4 : 몫이 우리가 구하고자하는 년도에 4의 배수가 몫만큼 있다.
// (year-1)/100 : 만약에 100의 배수가 있으면 100의 배수가 있는 몫만큼 뺀다.
// (year-1)/400 : 그리고 400의 배수가 있으면 400의 배수가 있는 몫만큼 더한다.
// 2) 구하고자 하는 해당년도의 month-1까지 합하기
// ex) 2010년 5월 1일 이면 -> 31일(1월) + 28일(2월) + 31일(3월) + 30일(4월) + 1 / ex) 3년 2월 13일 365(1년)+365(2년)+31(1월)+13(2월) = 총날짜수
// 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
// 31+28+31+30+31+30+31+31+30+31+30+31
// 풀이3) [가장 간결하고 좋은코딩]*** 733893 잘나옴
int[] m = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
for (int i = 0; i < month - 1; i++) totalDays += m[i]; // 이전달까지 합구하는 것
if(days06.Ex06_02.isLeapYear(year) && month >= 3) totalDays++; // 윤년일 때 일수 +1
totalDays += date;
/*
// 풀이2) 733893
for (int i = 1; i < month; i++) {
switch (i) {
case 2:
totalDays += (days06.Ex06_02.isLeapYear(year)) ? 29 : 28;
break;
case 4: case 6: case 9: case 11:
totalDays += 30;
break;
default:
totalDays += 31;
break;
} // switch
} // i for
totalDays+=date;
*/
/*
// 풀이1) 전체 로직을 이해하는 코드
switch (month) { // 5월
case 1:
totalDays += 1;
break;
case 2:
totalDays += 31 + 1;
break;
case 3: // case 3 윤년 +1
totalDays += 31+28 + 1;
break;
case 4:
totalDays += 31+28+31 +1;
break;
case 5:
totalDays += 31+28+31+30 + 1;
break;
case 6:
totalDays += 31+28+31+30+31 + 1;
break;
case 7:
totalDays += 31+28+31+30+31+ 30+ 1;
break;
case 8:
totalDays += 31+28+31+30+31+ 30+31 + 1;
break;
case 9:
totalDays += 31+28+31+30+31+ 30+31+31 + 1;
break;
case 10:
totalDays += 31+28+31+30+31+ 30+31+31+30+ 1;
break;
case 11:
totalDays += 31+28+31+30+31+ 30+31+31+30+31+ 1;
break;
case 12:
totalDays += 31+28+31+30+31+ 30+31+31+30+31+30+ 1;
break;
}
if( days06.Ex06_02.isLeapYear(year) && month >=3) totalDays++;
*/
return totalDays;
} // getTotalDays
1-2. 총날짜수 % 7 => 요일에 해당되는 정수값 구하기
private static int getDayOfWeek(int year, int month) {
// 총날짜수: 733893
int totalDays = getTotalDays(year, month, 1);
// System.out.println("> 총날짜수 : " + totalDays);
int dayOfWeek = totalDays % 7;
return dayOfWeek;
} // getDayOfWeek
1-3. 해당 월의 마지막 날짜 가져오기
private static int getLastDay(int year, int month) {
int lastDay;
switch (month) {
case 2:
lastDay = (days06.Ex06_02.isLeapYear(year)) ? 29 : 28;
break;
case 4: case 6: case 9: case 11:
lastDay = 30;
break;
default:
lastDay = 31;
break;
} // switch
return lastDay;
} // getLastDay
1-4. 달력 출력하기(1-1 ~ 1-3의 메서드를 다 사용)
private static void printCalender(int year, int month) {
// 1) 총날짜수 계산하기 : 1년1월1일 ~ n년n월n일 -> 1년1월1일 ~ 2010년5월1일
// 총날짜수 : 733893
int totalDays = getTotalDays(year, month, 1); // 년월일을 주면 총날짜수 계산 : 1일로 시작되는 요일을 구하는 것이기 때문에 date는 1일
// System.out.println("> 총날짜수 : " + totalDays);
// 2) 총날짜수 % 7 => 요일에 해당되는 정수값(0~6)
int dayOfWeek = getDayOfWeek(year, month);
// System.out.println("> dayOfWeek=" + "일월화수목금토".charAt(dayOfWeek);
// 3) 마지막 날짜 가져오기
int lastDay = getLastDay(year, month);
// System.out.println("> 마지막 날짜 : " + lastDay);
// 4) 달력 출력
System.out.printf("\t\t\t%d년 %d월\n", year, month);
String week = "일월화수목금토";
days08.Ex02.drawLine(60,'-');
for (int i = 0; i < week.length(); i++) System.out.printf("\t%c", week.charAt(i));
System.out.println();
days08.Ex02.drawLine(60,'-');
// 1일 ~ 31일
for (int i = 0; i < dayOfWeek; i++) { // 1일이 토요일에 맞춰서 출력하려면 i <= 6인데 마침 dayOfWeek 값이 6이라 바꿔도 됨 + 아래 코딩으로인해 = 연산자 빼기
System.out.print("\t");
}
// ASCII 찍는 것과 동일
for (int i = 1; i <= lastDay; i++) {
System.out.print("\t" + i);
if((dayOfWeek + i) % 7 == 0) System.out.println(); // 공백을 포함(dayOfWeek)시켜서 7로 나누었을 때 0으로 떨어지면 개행
}
System.out.println();
days08.Ex02.drawLine(60,'-');
} // printCalender
위와 같이 4개의 메서드를 다 선언했다면 main() 메서드 안에 아래와 같이 코딩을 하면 2010년 5월 달력이 출력된다.
printCalender(year, month); // 메서드 호출 부분
for문을 이용하면 원하는 년도와 월의 달력을 마음대로 출력할 수 있다.
// 메서드 호출 부분 - 2008년 1월 ~ 2010년 12월 달력 출력
for (int j = 2008; j <= 2010; j++) {
for (int i = 1; i <= 12; i++) {
printCalender(j, i);
}
}
// 메서드 호출 부분 - 2010년 1월 ~ 12월 달력 출력
for (int i = 1; i <= 12; i++) {
printCalender(year, i);
}
☞ 참고
여기서 사용된 isLeapYear()메서드와 drawLine()메서드는 다른 패키지에서 작성한 함수이다. days06과 days08 글을 보면 활용할 수 있을 것 같다.
2. 10진수를 2바이트 2진수로 변환하여 출력하기
import java.util.Arrays;
import java.util.Scanner;
public class Ex02 {
public static void main(String[] args) {
// [문제]
// 정수(int) 입력받아서 ex) 10진수 10
// 2바이트 2진수로 출력 2진수 00000000 00001010
// Arrays.toString(배열명); -> 확인용으로 배열 값을 출력해줌 > [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0]
int n;
Scanner sc = new Scanner(System.in);
System.out.println("> 10진수 정수를 입력하세요?");
n = sc.nextInt();
int[] binary = new int[16];
int idx = binary.length-1;
int share = n; // 몫
int rest; // 나머지
while(share != 0) {
share = n / 2; // 몫
rest = n % 2; // 나머지 -> 가장 마지막 방부터 채워넣기
binary[idx] = rest;
idx--;
n = share; // 몫을 다시 n으로 만들자
} // while
System.out.println(Arrays.toString(binary));
// String.replaceAll()메서드
System.out.println(Arrays.toString(binary).replaceAll(",\\s", "")); // 모든 , + 공백 => 빈문자열로 바꿔라
} // main
} // class
2-1. 10진수를 16진수로 출력하기
import java.util.Arrays;
import java.util.Scanner;
public class Ex02_03 {
public static void main(String[] args) {
int n ;
Scanner scanner = new Scanner(System.in);
System.out.print("> 10진수 정수 입력 ? "); // 10
n = scanner.nextInt();
// 10진수 10을 -> 16진수로 출력 a
char [] hex = new char[4];
Arrays.fill(hex, '0');
int share = n; // 몫 변수
int rest; // 나머지 변수
int idx = hex.length-1;
while( share != 0 ) {
share = n / 16; // 5
rest = n % 16; // 0
// 나머지(rest) 값을 문자로 변환해서 char[] hex에 저장하겠다.
// 1 + 48 -> '1'
// 10+87 -> 'a'
char value = (char)( rest += rest >= 10 ? 87 : 48 );
// System.out.printf("[%d]", rest); // [0][1][0][1] 1010
hex[idx--] = value;
n = share;
}
System.out.println("0x"+ Arrays.toString(hex).replaceAll(",\\s", ""));
} // main
} // class
3. 돈을 최적의 화폐단위로 계산하여 출력하기
코드1)
import java.util.Scanner;
public class Ex03 {
public static void main(String[] args) {
int money;
Scanner sc = new Scanner(System.in);
System.out.println("> 머니를 입력하세요?"); // 125,760 엔터
money = sc.nextInt();
// 화폐단위 : 5만원, 1만원, 5천원, 1천원, 5백원, 1백원, 5십원, 1십원, 5원, 1원
// 5만원 : 2장 25,760원
// 1만원 : 2장 5,760원
// 5천원 : 1장 760원
// 5백원 : 1개 260원
// 1백원 : 2개 60원
// 5십원 : 1개 10원
// 1십원 : 1개 0원
int share, rest;
// 풀이2)
int[] unit = {50000, 10000, 5000, 1000, 500, 100, 50, 10, 5, 1};
String[] s_unit = {"5만원", "1만원", "5천원", "1천원", "5백원", "1백원", "5십원", "1십원", "5원", "1원"};
// 반복문 사용 처리 : 5만원 ~ 1십원까지 10개이니까 for문 사용
for (int i = 0; i < unit.length; i++) { // 범위는 수정할 수도 있으니 배열의 길이로 설정
share = money / unit[i]; // 몫
rest = money % unit[i]; // 나머지(잔액)
System.out.printf("%s : %d개 %d\n", s_unit[i], share, rest);
money = rest;
} // i for end
/*
// 풀이1) 로직 파악하는 코딩
share = money / 50000; // 몫
rest = money % 50000; // 나머지(잔액)
System.out.printf("5만원 : %d개 %d\n", share, rest);
money = rest;
share = money / 10000; // 몫
rest = money % 10000; // 나머지(잔액)
System.out.printf("1만원 : %d개 %d\n", share, rest);
money = rest;
share = money / 5000; // 몫
rest = money % 5000; // 나머지(잔액)
System.out.printf("5천원 : %d개 %d\n", share, rest);
money = rest;
share = money / 1000; // 몫
rest = money % 1000; // 나머지(잔액)
System.out.printf("1천원 : %d개 %d\n", share, rest);
*/
} // main
} // class
코드2) boolean sw를 사용하여 푼 코드
4. 배열
/*
* 1. 배열의 정의? 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것
* 동일한 자료형이 메모리 상에 연속적으로 놓이게 한 것
*
* 2. 배열 선언 형식
* 자료형[] 배열명; // 배열명을 변수, 참조변수(주소 값을 참조하기때문에)이라고 한다.
* 자료형 배열명[];
*
* 3. 배열 생성 형식
* new 연산자를 사용해서 힙(동적)영역에 실제 기억공간이 할당되고 그 시작 주소를 배열명이 참조한다.
* 배열명 = new 자료형[배열크기];
*
* 4. 예) []인덱스(index) 연산자를 설명 - 배열
* 1000명의 국어점수를 저장할 변수를 선언
* int[] kors -> 스택영역에 생성
* kors = "new int[1000]" -> new를 통해 힙(동적)영역에 있는 주소를 kors가 참조
*
* 5. 배열의 요소
* 첨자값 == index(인덱스)
* 0번째 요소 배열명[0]
* 1번째 요소
* 2번째 요소
*
* 999번째 요소 배열명[999] == 배열명[배열명.length-1]
*
* 6. 배열크기 == 배열명.length
*
* 7. 배열의 길이 변경 p189 Ex04_02.java
*
* 8. 배열의 초기화 p189
*
* 9. 배열을 초기화하지 않으면 각 자료형의 기본값으로 초기화가 되어져 있다.
* ex) int[] m = new int[3];
* int의 기본값인 0으로 초기화 되어져 있다.
* m[0] = 0;
* m[1] = 0;
* m[2] = 0;
*/
4-1. 배열 선언 및 생성 / 배열 출력 / 배열을 사용할 때 가장 많이 발생하는 에러 메시지
4-2. 배열의 길이 변경(증가) 메서드 만들기 ***
public class Ex04_04 {
public static void main(String[] args) {
int[] m = new int[3];
m[0] = 100;
m[1] = 85;
m[2] = 93;
// 2개의 정수를 더 저장을 해야 된다.
// m 배열의 크기(길이)를 2개 더 증가(변경)
m = increaseArraySize(m, 5);
m[3] = 80;
disp(m);
} // main
public static int[] increaseArraySize(int[] m, int n) { // increaseArraySize 메서드로 인해 스택영역에 m 배열 생성, main()의 m과 같은 힙영역 주소를 참조
int[] temp = new int[m.length + n]; // 원래 배열크기(main과 동일한 m이 참조하는 주소를 가짐) + n 만큼 증가한 것을 스택영역에 temp를 생성하여 저장
for (int i = 0; i < m.length; i++) {
temp[i] = m[i]; // temp에 m이 가지고 있는 요소의 값을 복사
}
// increaseArraySize = temp;
// m = temp;
return temp; // 스택영역에 생긴 temp가 참조하는 힙영역에 있는 m을 main에 리턴
} // increaseArraySize
private static void disp(int[] m) {
for (int i = 0; i < m.length; i++) {
System.out.printf("m[%d] = %d\n", i, m[i]);
}
} // disp
} // class
* 배열의 단점
배열의 크기를 설정한 후에는 배열의 크기가 자동으로 변경되지 않는다.
-> 컬렉션(Collection) 사용 -> 배울 예정
코드) 배열의 크기가 부족하다면 위에서 만든 increaseArraySize 메서드를 사용하여 배열 크기를 증가시키기
5. 한 반에 30명의 학생 이름, 국어, 영어, 수학, 총점, 평균, 등수 처리하기
-> 내일 이어서 마무리 할 예정
현재까지 작성된 코드)
package days11;
import java.util.Scanner;
/**
* @author Yelin
* @date 2022. 3. 3. - 오후 5:11:27
* @subject
* @content
*/
public class Ex07 {
public static void main(String[] args) {
// 한 반에 30명의 학생
// 이름, 국어, 영어, 수학, 총점, 평균 등수를 처리하는 코딩
Scanner sc = new Scanner(System.in);
final int STUDENT_COUNT = 30;
String[] names = new String[STUDENT_COUNT];
int[] kors = new int[STUDENT_COUNT];
int[] engs = new int[STUDENT_COUNT];
int[] mats = new int[STUDENT_COUNT];
int[] tots = new int[STUDENT_COUNT];
double[] avgs = new double[STUDENT_COUNT];
int[] ranks = new int[STUDENT_COUNT];
// 입력받은 학생의 수 + 각 배열의 채워넣을 위치(인덱스)
int count = 0;
char con = 'y';
do {
System.out.printf("> [%d]번 이름 국어 영어 수학 입력하세요?", count+1);
String name = sc.next();
int kor = sc.nextInt();
int eng = sc.nextInt();
int mat = sc.nextInt();
int tot = kor + eng + mat;
double avg = (double)tot / 3;
int rank = 1; // 전체 학생의 점수를 받아야 등수를 매길 수 있으니 기초값 1로 설정
names[count] = name;
kors[count] = kor;
engs[count] = eng;
mats[count] = mat;
tots[count] = tot;
avgs[count] = avg;
ranks[count] = rank;
count++; // 입력받은 학생수 1증가 + 채워넣을 인덱스 값도 1증가
System.out.println("> 계속 하시겠습니까?");
con = sc.next().charAt(0);
} while (Character.toUpperCase(con) == 'Y');
System.out.println("> 입력받은 학생 수 : " + count + "명");
// 입력받은 학생 정보 출력
for (int i = 0; i < count; i++) {
System.out.printf("%s\t%d\t%d\t%d\t%d\t%.2f\t%d\n", names[i], kors[i], engs[i], mats[i], tots[i], avgs[i], ranks[i]);
}
} // main
} // class
'TIL > Java' 카테고리의 다른 글
[SIST] Java_days13 (0) | 2022.03.07 |
---|---|
[SIST] Java_days12 (0) | 2022.03.04 |
[SIST] Java_days10 (0) | 2022.03.02 |
[Java] char배열과 String 클래스의 변환_new String() / toCharArray() (0) | 2022.03.01 |
[Java] 배열 관련 코드예제와 Arrays.toString() / System.arraycopy() (0) | 2022.03.01 |