1. 피보나치 수열
- 앞의 두 수의 합이 바로 뒤의 수가 되는 배열
ex) 1 + 1 + 2 + 3 + 5 + 8 + 13 + 21 + 34 + 55 + 89 + 144 + 233 ...
> 문제 : 150보다 작거나 같은 n항의 값과 총 합을 구하기
* 배열로 푸는 것은 n 값이 얼마나 나올지 모른다고 가정하면 배열의 길이를 정할 수 없기 때문에 배열로 푸는 것은 추천하지 않는다고 하셨다. 그래도 로직을 이해하고 도움이 될 수 있어 내용 정리할 때는 포함시키기로 하였다.
코드 1) 배열 사용
int[] m = new int[150];
m[0] = 1;
m[1] = 1;
int sum = m[0] + m[1];
System.out.print("1+1+");
for (int i = 2; i < m.length; i++) { // for (int i = 2; i < m.length && m[i] <= 150; i++)
m[i] = m[i-2] + m[i-1];
if(m[i] > 150) break; // for문 안에 '&& m[i] <= 150; i++)' 코딩을 했을 경우에는 해당 코딩 삭제
System.out.print(m[i] + "+");
sum += m[i];
}
System.out.print("=" + sum);
코드 2)
while (true) {
next = first + second;
if(next > 150) {
System.out.println("\b=" + sum);
System.exit(-1);
}
System.out.print(next + "+");
sum += next;
first = second;
second = next;
}
코드 3) 위의 코드와 동일한 코드이며 더욱 간결한 코드이다.
만약, 코드 3)의 코드를 아래와 같이 푼다면 문제점이 있다.
while (next < 150) { // 144 < 150 참 일 경우
next = first + second; // next = 89+144 > 233
first = second; // 144
second = next; // 233
sum += next; // 233
System.out.println(next); // 233
}
next가 144일 때 while문 조건이 true가 되어 {} 블럭 안에 있는 코드가 수행이 되는데
{} 블럭 안 코드 중 next = first + second를 해버리면 값이 233이 나오기 때문에 항의 값이 150을 넘어버리게 된다.
이점을 유의하자!
2. 카드 번호 랜덤하게 특정 위치 4자리 숫자를 **** 출력하기
코드)
2-1. String 클래스 메서드
// 1. 문자열의 길이
System.out.println(card.length());
// 2. 문자열 속에서 원하는 위치의 한 문자 : charAt(index)
// 3. String.format() : 어떤 데이터를 내가 원하는 형식의 문자열로 만들어서 반환해주는 메서드
// String data = String.format("%s-%s-%s-%s\n", cardNumbers[0], cardNumbers[1], cardNumbers[2], cardNumbers[3]);
// 4. String.matches(pattern) 메서드
// 5. String.split() 메서드
String regex = "-";
String[] cardNumbers = card.split(regex);
for (int i = 0; i < cardNumbers.length; i++) {
System.out.println(cardNumbers[i]);
}
// 6. String.join() 메서드
card = String.join("-", cardNumbers);
System.out.println(card);
String rrn = "830412-1700001";
// 7. String.substring(시작 인덱스, 끝인덱스) End 인덱스 앞 위치 값까지 읽어온다.
beginIndex <= index < endIndex
System.out.println(rrn.substring(0, 6)); // 830412
System.out.println(rrn.substring(7, 14)); // 1700001
System.out.println(rrn.substring(7)); // endIndex를 생략하면 문자열 끝까지를 나타낸다.
System.out.println(rrn.substring(0, 8) + "******"); // 830412-1******
3. 주민등록번호 가리기
String rrn = "830412-1700001"; // 변수 선언
코드1) toCharArray()메서드와 new String() 메서드 사용
코드2) String.substring() 메서드 사용
System.out.println(rrn.substring(0, 6)); // 830412
System.out.println(rrn.substring(7, 14)); // 1700001
System.out.println(rrn.substring(7)); // endIndex를 생략하면 문자열 끝까지를 나타낸다.
System.out.println(rrn.substring(0, 8) + "******"); // 830412-1******
코드3) String.split()과 String.join() 메서드 사용
String[] rrnArr = rrn.split("-");
rrnArr[1] = rrnArr[1].charAt(0) + "*****";
rrn = String.join("-", rrnArr);
System.out.println(rrn);
코드4) String.split()과 String.join() 메서드 사용
String[] rrnArr = rrn.split("-");
rrnArr[1] = "*******";
rrn = String.join("-", rrnArr);
System.out.println(rrn);
4. main() 메서드의 매개변수 String[] args의 의미/활용
+ 이 부분은 추후에 다시 자세히 설명해주신다고 하셨다.
1) main 메서드는 언제 호출되어지는가?
> javac.exe Ex04.java Ex04.class
> java.exe Ex04 매개변수 매개변수... > main 안에 있는 매개변수(args)로 들어가짐 실행 -> 시작객체(Ex04 클래스) -> main() 메서드를 호출해서 실행
명령 프롬프트에서만 할 수 있는게 아니라 이클립스에서도 할 수 있다!
이전에 만들었던 윤년/평년 출력하는 함수를 import해서 클래스 파일에 int year 변수를 선언하고 args[0]이라고 넣어준 다음에..
- Class 파일 우클릭 > Run As > Run Configurations 클릭 > Argument 탭에서 매개변수(ex. 2100) 입력 후 Run 하면
콘솔창에 출력이 아주 잘 된다!
5. 주민등록번호로 성별, 생년월일, 나이(만/세는나이) 출력하기 / 검증하기
다양한 문제를 풀기 전에 주민등록번호의 개요를 먼저 살펴봐야한다. (스크롤 주의..!)
* [주민등록번호]
* 1. 개요 - 요구분석서
* ㄱ. 영어: Resident Registration Number, RRN
* ㄴ. 주민등록법에 의해 등록
* ㄷ. 대한민국에서 대한민국에 거주하는 모든 국민에게 발급
* ㄹ. 1968년 11월 21일부터 편리한 [간첩 식별 등의 목적]으로 주민등록증이 발급
* ㅁ. 1975년 3개편 ㄱㄴㄷㄹㅁㅂ - ㅅㅇㅈㅊㅋㅌㅍ 13자리
* ㅂ. 'ㄱㄴㄷㄹㅁㅂ' 여섯 숫자는 생년월일 [830412]-1700001
* 83년 4월 12일 > 19xx/18xxx/20xx
* ㅅ. 'ㅅ'은 성별 830412-[1]700001
* 출생년도(세기)
* 9 : 1800 ~ 1899년에 태어난 남성(현재 대부분 사망)
* 0 : 1800 ~ 1899년에 태어난 여성(현재 대부분 사망)
* 1 : 1900 ~ 1999년에 태어난 남성
* 2 : 1900 ~ 1999년에 태어난 여성
* 3 : 2000 ~ 2099년에 태어난 남성
* 4 : 2000 ~ 2099년에 태어난 여성
* 5 : 1900 ~ 1999년에 태어난 외국인 남성
* 6 : 1900 ~ 1999년에 태어난 외국인 여성
* 7 : 2000 ~ 2099년에 태어난 외국인 남성
* 8 : 2000 ~ 2099년에 태어난 외국인 여성
* ㅇ. 'ㅇㅈㅊㅋ'는 출생등록지 830412-1[7000]01
* 1) ㅇㅈ 출생지역
* 서울특별시 : 00~08
* 부산광역시 : 09~12
* 인천광역시 : 13~15
* 경기도 : 16~25
* 강원도 : 26~34
* 충청북도 : 35~39
* 대전광역시 : 40~41
* 충청남도 : 42~47
* 세종특별자치시 : 44, 96[10]
* 전라북도 : 48~54
* 전라남도 : 55~66
* 광주광역시 : 55, 56
* 대구광역시 : 67~69, 76
* 경상북도 : 70~75, 77~81
* 경상남도 : 82~84, 86~89, 90~92
* 울산광역시 : 85, 90
* 제주특별자치도 : 93~95
* 2) ㅊㅋ 주민센터 고유번호
* ㅈ. ㅌ’은 일련번호로, 그날 주민센터에서 출생신고를 한 순서 830412-17000[0]1
* ㅊ. ㅍ’은 주민등록번호에 오류가 없는지 확인하는 검증번호 830412-170000[1]
* ㅍ = 11-{(2×ㄱ+3×ㄴ+4×ㄷ+5×ㄹ+6×ㅁ+7×ㅂ+8×ㅅ+9×ㅇ+2×ㅈ+3×ㅊ+4×ㅋ+5×ㅌ) mod 11}
* 즉, 소괄호 안에 있는 것을 계산한 값을 11로 나눠서 나온 나머지를 11에서 뺀 값이 ㅍ이다. (단, 10은 0, 11은 1로 표기한다.
5-1. 주민등록번호로 성별 출력하기
import java.util.Scanner;
public class Ex05_02 {
public static void main(String[] args) {
String rrn = getRRN();
System.out.println(rrn);
// 1. 주민등록번호로부터 성별을 출력 ex)"남자", "여자"
boolean gender = getGender(rrn);
System.out.println(gender ? "남자" : "여자");
} // main
// 기능 : 주민등록번호를 가지고 남자 true, 여자 false
// 매개변수 : 체크하고자 하는 주민등록번호 rrn
// 리턴값 + 리턴자료형 : true/false boolean
private static boolean getGender(String rrn) { // 남/여만 확인 가능 -> 재사용성 떨어지는 함수
// 남자 -> 1/3/5/7/9
/*
// 내가 푼 코딩
boolean gender;
char[] ch = rrn.toCharArray();
gender = ch[7] == 0 || ch[7] % 2 == 0 ? false : true;
return gender;
*/
// 풀이 4) 정규표현식
return rrn.substring(7, 8).matches("[13579]");
/*
// 풀이 3) substring
if(Integer.parseInt(rrn.substring(7, 8)) % 2 == 1) return true;
else return false;
// return Integer.parseInt(rrn.substring(7, 8)) % 2 == 1; // 풀이3과 동일한 코딩 -> 이 값자체가 t/f 반환
*/
/*
// 풀이2) charAt
return (rrn.charAt(7)-48) % 2 == 1 ? true: false; // *** 48을 꼭 빼줘야 함.charAt(7)이 '1'이면 숫자 49이기 때문에
// return (rrn.charAt(7)-48) % 2 == 1; // 위의 코딩과 동일한 코딩 -> 이 값자체가 t/f 반환
*/
/*
// 풀이1) charAt
if( (rrn.charAt(7)-48) % 2 == 1) return true;
else return false;
*/
} // getGender
// 주민등록번호 입력 후 유효성검사
public static String getRRN() {
String rrn, regex = "\\d{6}-\\d{7}";;
Scanner sc = new Scanner(System.in);
do {
System.out.println("> 주민등록번호 입력?");
rrn = sc.next();
} while (!rrn.matches(regex));
return rrn;
} // getRRN
} // class
> 주의할 점 : charAt() 메서드를 사용할 시 문자 '1'은 숫자 49로 인식되므로 꼭 -48을 해주어야 한다.
String rrn = "830412-1700001";
// System.out.println(rrn.substring(7, 8)); // 문자열 "1"
// System.out.println(rrn.charAt(7)); // 문자 '1'
// System.out.println(rrn.charAt(7)-1); // 문자 '1' => 49 이므로, 49-1 == 48 로 출력
5-2. 주민등록번호로 생년월일 출력하기
public class Ex05_04 {
public static void main(String[] args) {
// days10 동일한 패키지 안에 있을 경우에는 패키지 명을 입력하지 않아도 됨
// [days10].Ex05_02.getRRN()
// 패키지명.클래스명.메서드명()
String rrn = Ex05_02.getRRN(); // 990112-1411001
System.out.println(rrn);
String birthday = getBirth(rrn); // 1999년 01월 12일
System.out.println(birthday);
} // main
// 1. 기능 : 주민번호로부터 생년월일을 반환하는 메서드
// 2. 매개변수 : 주민등록번호 rrn
// 3. 리턴값+리턴자료형 : 생년월일 String ex) 1999년 01월 12일
public static String getBirth(String rrn) {
int year = Integer.parseInt(rrn.substring(0,2)); // 99
int month = Integer.parseInt(rrn.substring(2,4)); // 1
int day = Integer.parseInt(rrn.substring(4,6)); // 12
// year = 99 -> 1999 / 1899 / 2099
// 성별(ㅅ)
// 0 9 -> 1800년대
// 1 2 5 6 -> 1900년대
// 3 4 7 8 -> 2000년대
// rrn.charAt(7)-48 // '1'
switch (rrn.charAt(7)-48) {
case 0: case 9:
year += 1800;
break;
case 1: case 2: case 5: case 6:
year += 1900;
break;
default:
year += 2000;
break;
}
// String.format() 내가 원하는 형식의 문자열로 변환
String birthday = String.format("%d년 %02d월 %d일", year, month, day);
return birthday;
} // getBirth
} // class
5-3. 주민등록번호로 만나이와 세는나이 출력하기
- 만나이 : 태어난 일을 기준으로 1년이 지나야지 1살을 먹는다.
- 세는나이 : 사람이 태어남과 동시에 한 살로 치고 그 후 새해의 1월 1일마다 한 살을 먹는다.
public class Ex05_05 {
public static void main(String[] args) {
/*
* 전세계적으로 만나이 : 태어난 일을 기준으로 1년이 지나야지 1살을 먹는다
* 대한민국은 세는 나이 : 사람이 태어남과 동시에 한 살로 치고 그 후 새해의 1월 1일마다 한 살을 먹는다
*
* A사람
* 2019.12.30 2019.12.31 2020.1.1 2020.12.29 2020.12.30 2021.1.1
* 만나이 0살 0살 0살 1살 1살
* 세는나이 1살 2살 2살 2살 3살
*/
String rrn = Ex05_02.getRRN();
// int 세는나이 = get세는Age(rrn);
// System.out.println(세는나이);
int 만나이 = get만Age(rrn);
System.out.println(만나이);
} // main
private static int get만Age(String rrn) {
// 만나이 = 태어난 일을 기준으로 1살 먹기
// 만나이? 2019.01.13 태어나면 2020.01.13에 1살, 2021.01.13에 2살
// 계산방법 1) 몫(나이) == 총 살아온 일수 / 365.25
// 계산방법 2) 올해 - 생일년도 -1 (생일 지났는지 여부)
// 2022 - 2019
// 생일이 지나지 않은 경우 3살 -1 = 2살
// 생일이 지난 경우 3살
// 강사님이 풀어주신 코딩 -> Date 클래스의 객체(있는 메서드 활용하면 쉽다)
// true/false 생일날짜객체.before(현재날짜객체)
// d.after(d2)
// d.before(d)
/*
// 월
// 890112이고 오늘 3월 2일이면..
int birthMD = Integer.parseInt(월일); // 0112 -> 112
int nowMD = Integer.parseInt(오늘월일); // 0302 ->302
if(birthMD < nowMD) age--;
*/
// 풀이1)
int age;
Date d = new Date();
int now = d.getYear() + 1900; // int now = 2022;
int month = d.getMonth() + 1;
int date = d.getDate();
int yearBD = Integer.parseInt(Ex05_04.getBirth(rrn).substring(0, 4)); // "1999년 01월 12일" -> 1999로 가져오기
int monthBD = Integer.parseInt(Ex05_04.getBirth(rrn).substring(6, 8));
int dateBD = Integer.parseInt(Ex05_04.getBirth(rrn).substring(10, 12));
age = now - yearBD;
// 올해 3월 2일 생일 12월 17일 -> 로직 잘못됨 내 만나이 26살인데 27살로 나옴...
if(!(monthBD >= month && dateBD >= date)) age--;
// if(monthBD < month && dateBD < date) age--;
return age;
} // get만Age
private static int get세는Age(String rrn) {
int age;
Date d = new Date();
int now = d.getYear() + 1900; // int now = 2022;
int yearBD = Integer.parseInt(Ex05_04.getBirth(rrn).substring(0, 4)); // "1999년 01월 12일" -> 1999로 가져오기
age = now - yearBD + 1;
return age;
// 내가 푼 코딩
/*
int age;
int year = Integer.parseInt(rrn.substring(0,2));
switch (rrn.charAt(7)-48) {
case 0: case 9:
year += 1800;
break;
case 1: case 2: case 5: case 6:
year += 1900;
break;
default:
year += 2000;
break;
}
age = 2022-year+1;
return age;
*/
} // get세는Age
} // class
☞ 참조
- 현재 년도를 가지고 오는 메서드
5-4. 주민등록번호 검증하기
주민등록번호의 맨 마지막 자리는 다음과 같은 규칙으로 검증을 한다.
* 11-{(2×ㄱ+3×ㄴ+4×ㄷ+5×ㄹ+6×ㅁ+7×ㅂ + 8×ㅅ+9×ㅇ+2×ㅈ+3×ㅊ+4×ㅋ+5×ㅌ) % 11}
위의 식과 마지막 자리가 같다면 올바른 주민등록번호이다.
'TIL > Java' 카테고리의 다른 글
[SIST] Java_days12 (0) | 2022.03.04 |
---|---|
[SIST] Java_days11 (0) | 2022.03.03 |
[Java] char배열과 String 클래스의 변환_new String() / toCharArray() (0) | 2022.03.01 |
[Java] 배열 관련 코드예제와 Arrays.toString() / System.arraycopy() (0) | 2022.03.01 |
[Java] System.in.read() / System.in.skip() / System.in.available() (0) | 2022.02.27 |