TIL #10 - 각 종 응용들
#main 메소드
main 메소드는 JVM에 의한 콜백 메소드이다.
콜백 메소드란 실행 시 JVM이나 운영체제에 의해 불려지는 것이다.
main 메소드는 컴파일 시엔 호출되지 않는다.
단, 출력할 때 main 메소드를 호출한다.
public static void main(String[] args) { }
main 메소드를 잘 보면 String 타입의 배열이 들어 있는 것을 볼 수 있다.
현재 main 메소드는 배열에 대한 주소값만 가지고 있다.
그래서 main 메소드의 배열 args에 값을 넣을 수도 있는 것이다.
args 배열의 배열명을 보자
System.out.println("배열명 args = " + args);
[결과]
배열명 args = [Ljava.lang.String;@15db9742
배열명은 참조값으로 이루어져 있는데 그 참조값은 클래스명@16진수로 표현되기 때문에 위와 같은 결과가 나왔다.
+ 확장형 for문
확장형 for문은 앞서서도 언급했지만, 값을 처음부터 끝까지 쭉 나열할 때 주로 쓴다.
만약 배열 args에 들어있는 값들 data를 출력하고자 한다면 아래와 같은 코드가 만들어 진다.
for(String data : args) {
System.out.println(data);
}
# 형변환 Casting
형변환은 주의할 것이 기본형은 기본형끼리, 객체형은 객체형끼리만 가능하다.
예를 들어 기본형인 int는 객체형인 String으로 형변환 불가하다.
args 배열의 index 0과 index 1의 값을 각각 형변환해주는 코드이다.
class MethodTest4{
public static void main(String[] args) {
int a = Integer.parseInt(args[0]); // 숫자형의 문자열을 10진수의 정수형으로 바꿔줌
double b = Double.parseDouble(args[1]); // 문자열을 실수형으로 바꿔줌
System.out.println(a+ " + " + b +" = " + (a+b));
}
}
args는 현재 String 타입의 배열들이다.
이 배열들 중 index 0 번째에는 int a를, index 1번째에는 double b를 넣는 것은 불가능하다.
하지만, Integer.parseInt 와 Double.parseDouble을 통해 각각의 값들을 int형과 double형으로 형변환 해주었다.

결과가 잘 나왔다.
(공부를 위해서 cmd 창에서 실행했습니다..)
# 구구단
구구단 프로그램이다.
단을 입력 받아서 구구단을 출력한다.
class GuguDan {
public static void main(String[] args) {
System.out.println("java GuguDan");
int n = Integer.parseInt(args[0]);
for(int i = 1; i <= 9; i++){
System.out.println(n + " * " + i + " = " + (n*i));
}
}
}
위의 코드도 역시 String 배열인 args를 Intger.parseInt를 통해 int형으로 바꿔준 다음 입력을 받았다.

# 1부터 100 중 난수를 하나 발생해 맞추는 게임
1부터 100까지 난수를 하나 발생시켜 사용자가 맞추는 게임이다.
정답이 난수보다 크면, 크다고
작으면 작다고 힌트를 주고 마지막엔 몇번의 시도가 있었는지도 알려준다.
import java.util.Scanner;
class Quiz {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int num = (int)(Math.random()*100)+1; // 1부터 100까지
// int num = (int)(Math.random()*(끝값 - 시작값 +1))+시작값;
int answer; // 입력받을 답
System.out.println("1과 100 사이에 난수가 발생하였습니다. " );
int count = 0;
while(true){
System.out.print("숫자 입력 : ");
answer = scan.nextInt();
if(answer > num) {
System.out.println(answer + "보다 작습니다.");
count++;
}else if (answer < num) {
System.out.println(answer + "보다 큽니다");
count++;
}else if(answer == num) {
// 정답
break;
}
}
System.out.println("정답입니다");
System.out.println(count + "번 맞추셨습니다");
}
}
Math.random의 경우에는 공식이 있다.
(int)(Math.random()*(끝값 - 시작값 +1 )) + 시작값
위와 같이 하면 int형 정수 중에 내가 원하는 범위의 숫자를 난수로 뽑을 수 있다.
만약 25부터 90까지의 범위에서 난수를 하나 출력하고 싶다면 아래와 같다.
(int)(Math.random()*(66))+25
코드를 보면 while문을 true로 넣어 난수를 찾을 때까지 계속 코드가 돌아가게 만들었다
발생한 난수와 사용자가 입력한 값을 if문으로 비교를 하며 힌트를 주며
그럴 때마다 count++를 해서 입력 한 번을 기준으로 count를 1씩 증가시킨다
물론 count는 0으로 초기화 시켜놓은 상태이다.
만약 정답을 맞추면 (answer == num)이면
break; 를 입력해 while문에서 빠져나온다
그런 후 합산한 count값을 출력하며 코드를 마친다
# 난수 두개를 뽑아 더한 답을 맞추는 프로그램
이번엔 10부터 99 사이의 난수를 2개 발생시켜 합을 맞추는 프로그램이다.
만약 사용자가 답을 틀렸을 경우엔 한 번 더 기회를 주고
그래도 틀린다면 정답을 알려준다.
문제는 총 5개이고 맞출 때 마다 count를 해서 마지막에 점수를 구한다.
import java.util.Scanner;
class Quiz2 {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int a,b;
int user;
int count = 0;
System.out.println("덧셈의 합을 맞추어라 ");
// 5문제 나오게
for(int i = 1; i <=5; i++){
a = (int)(Math.random()*90)+10; // 10부터 99사이
b = (int)(Math.random()*90)+10;
for(int k = 1; k <= 2; k++){ // 틀렸을 때 1번 더 기회
System.out.print("["+ i + "]" + a + "+" + b + "=");
user = scan.nextInt();
if(user == (a+b)) {
System.out.println("참 잘했어요");
count++;
break; // k for문 나감
}else{
if(k == 1){
System.out.println("다시 한번 더 ");
}else {
System.out.println("틀렸습니다. 정답은" + (a+b) + "입니다. ");
}
}
}// for k
}// for i
System.out.println("당신의 점수는 "+ count + "번을 맞춰서 " + (count*20) + "점 입니다");
}
}
필드값으론 난수 a,b / 사용자에게 입력받을 값 user / 정답 횟수를 저장할 count가 있다.
문제는 총 5개이므로 for문은 1부터 5까지 돌린다.
for문 안에서 a와 b의 난수를 각각 뽑아낸다.
매번 새로운 난수를 만들어야하기 때문에 for문 안에서 만들어 낸다.
사용자가 정답을 틀렸을 경우엔 기회를 한 번 더 줄 것이기 때문에 for문을 하나 더 만든다
안 쪽 for문은 1부터 2까지 돌린다.
한 번 더 기회를 줄 때도 역시 앞에서 틀린 문제를 알려줘야하기 때문에
for문 안에서 문제를 알려준다.
그런 다음 사용자에게 입력을 받는다.
그런 후 if문이다.
만약 사용자가 정답을 맞추었을 경우에는 정답이라는 메세지와 함께
정답 횟수를 count++ 한다.
그리고 안쪽 for문에서 나간다.
(안 쪽 for문에서 나간 후엔 바깥 쪽 for문에 의해 다시 한 번 더 a, b 난수가 발생하여 새로운 문제가 만들어진다.)
만약 사용자가 정답을 틀렸을 경우엔 안쪽 k for문이 돌아간다는 뜻이기 때문에
k == 1이 된다 (k가 1부터 시작하기 때문이다)
그런 후 if문을 나가 다시 입력을 받는다.
하지만 그럼에도 틀린 경우엔 k가 ++가 되어 2가 되는데
그런 경우엔 else로 가 정답을 알려주며 안쪽 for문을 나간다.
제일 바깥 쪽 for문이 다 돌아가면
마지막으로 count를 세어서 점수를 계산한 후 출력한다.
# 성적 입출력 프로그램
성적을 입출력하고 정답 여부와 점수까지 알려주는 프로그램이다.
총 5문제에 대해 답을 상수 선언하고 입력받은 String 값이 상수와 맞으면 O, 틀리면 X를 출력한다.
import java.util.Scanner;
/*
이름 1 2 3 4 5 점수
홍길동 O X X O X 40
*/
class Quiz3 {
public static final String ANSWER = "11111"; // 상수화
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
String name; //이름
String input; // 학생의 답
int score; // 점수
char[] ox = new char[ANSWER.length()]; // 답인지 아닌지
System.out.println("이름을 입력하시오");
name = scan.nextLine();
System.out.println("답 5개를 입력하시오");
input = scan.nextLine();
// answer와 input을 비교해야한다.
// 그리고 일치하는 갯수를 count해서 출력
score = 0;
for(int i = 0; i < 5; i++){
if(input.charAt(i) == ANSWER.charAt(i)){
ox[i] = 'O';
score++;
}else {
ox[i] = 'X';
}
}
System.out.println("이름\t1\t2\t3\t4\t5\t점수");
System.out.println(name+"\t"+
ox[0]+"\t"+
ox[1]+"\t"+
ox[2]+"\t"+
ox[3]+"\t"+
ox[4]+"\t"+
(score*20));
}
}

먼저 답안지 용 상수를 선언한다.
답은 모두 11111 이다.
이 답과 사용자로부터 입력받을 값을 하나하나 비교할 것이다.
사용자의 이름 name, 그리고 답 input을 입력 받는다.
답 input역시도 문자열 String 타입이다.
이 둘을 입력받은 뒤 정답횟수를 저장할 count를 0으로 초기화 시켜주고
문제 5개에 따른 for문을 돌린다.
for문 안의 if문으로 입력받은 input과 정답 ANSWER를 비교하는데
이때 사용하는 메소드가 charAt() 이다.
charAt은 String 타입의 문자를 하나하나 골라낼 수 있다.
간단하게 보자면 아래와 같다.
String a = "abc";
System.out.println(a.charAt(1));
// 결과 b
charAt을 이용해서
input[0] == ANSWER[0]
....
input[4] == ANSWER[4]
이렇게 하나하나 비교하는 것이다.
그리고 만약, 이 둘이 일치하면
ANSWER의 길이 만큼 선언한 char 타입의 ox 배열의 값으로 'O' 를 넣는다.
만약 틀리면 'X'를 넣는다.
그런 후 출력한다.
# 배열
배열도 앞에서 많이 했지만 다시 정리해본다.
배열을 선언하는 것은 아래와 같다.
int[] arr;
만든 배열에 메모리를 할당하는 것은 (배열에 크기를 주는 것은) 아래와 같다.
arr = new int[5];
이 둘을 한 번에 하는 편리한 코드도 있다
int[] arr = new int[5];
위의 과정까지 하는 것이 배열에 index 까지 부여한 것이다.
배열의 크기가 5이므로 배열의 index는 0부터 4까지 있는 것이다.
배열의 길이는 항상 크기-1 이다.
아직은 비어있는 배열이지만, 이 배열에 값을 넣어줄 수도 있다.
arr[0] = 27;
arr[1] = 35;
arr[2] = 12;
arr[3] = 64;
arr[4] = 31;
물론 반복작업은 for문으로 만들 수도 있다.
위의 배열을 출력하는 코드이다.
for(int i = 0; i < arr.length; i++){
System.out.println("arr[" +i+ "]=" + arr[i]);
}
우리는 5라는 배열의 크기를 알고 있지만,
length를 통해 for문에게 알아서 배열의 길이만큼 for문을 수행하라고 할 수도 있다.
(이게 더 편한 방법이기도 하다 )
for문을 통해 배열을 거꾸로도 출력할 수 있다.
for(int i = arr.length-1; i >= 0; i--){
// arr.length-1
System.out.println("arr[" +i+ "]=" + arr[i]);
}
# 난수를 아스키코드로 만들어 각 아스키코드에 알파벳 각각이 몇개 들어 있는지 확인하는 프로그램
65에서 90 사이의 난수를 만들어 크기 50의 배열에 저장한다.
그리고 그것을 아스키코드로 만든다.
아스키코드로 만든 난수들을 알파벳 총 26개와 비교해 각각의 알파벳이 몇개 들어 있는지 알려줄 것이다.
public class ArrayTest2 {
public static void main(String[] args) {
int[] arr = new int[50]; //
int[] alpa = new int[26]; // 알파벳 갯수
for(int i = 0; i < arr.length; i++) {
arr[i] = (int)(Math.random()*26)+65;
// 65~ 90사이의 난수 만듦
// 배열 arr의 요소들을 아스키코드로 바꾸기
System.out.print((char)arr[i]+"\t");
// 배열을 10열로 배열
if((i+1) % 10 == 0) {
// i는 0부터 시작하기 때문에 첫번째 값의 나머지가 1이 되므로 +1
System.out.println();
}
for(int k = 0; k < alpa.length; k++ ) {
if(arr[i] == (k+65)) {
alpa[k]++;
// A의 아스키코드는 65다.
// 그렇기 때문에 alph[0] 일때 A가 65고
// alph[1] 일때 B가 66이 되기 때문에
// +1을 하면 자동적으로 인식이 가능하다.
}
}// for k
}// for i
// 출력
for(int i = 0; i < alpa.length; i++) {
System.out.println((char)(i+65)+"의 갯수" + alpa[i]);
}
}
}
먼저 크기가 50인 배열 arr을 만든다. 이 배열 안에 65에서 90사이의 난수를 넣을 것이다.
그런 다음 arr와 비교할 알파벳을 넣을 alpa 배열도 따로 만든다.
알파벳의 갯수가 26이므로 alpa 배열의 크기는 26이다.
이후 난수를 만든다.
난수는 65에서 90사이의 수들이다.
난수를 만들고 그것들을 arr 배열 안에 넣은 후 char을 통해 난수들을 아스키코드로 만든다.
난수 만드는 for문 아래의 if문은 단지 요소들을 10열로 정리하는 배열이다.
i+1을 한 이유는 0은 10을 나누면 1이 되어 열에서 홀로 벗어나기 때문이다.
그래서 0의 값을 없애기 위해 +1을 해주었다.
이제 아스키코드로 형변환시킨 난수들과 알파벳을 비교해보자.
만약 둘이 일치한다면 alpa가 ++ 될 것이다.
arr[i] == (k+65) 한 이유는,
A의 아스키 코드는 65이고
alpa[0] 일때 A가 65,
alpa[1] 일때 B가 66
점점 1씩 커지는 형태이기 때문에
65부터 시작해 비교하기 위함이다.
비교가 끝났다면 차곡차곡 ++ 해온 alpa를 출력한다.
# 주차장 관리
5대만 주차할 수 있는 주차장을 만들어
차가 들어오면 True, 나가면 False를 입력한다.
사용자는 1. 입차 2. 출차 3. 목록 4. 끝 의 선택지가 있고
입차시 입차 위치를 물어 해당 위치가 True 면 주차 불가/ False 면 주차
출차시 출차 위치 물어 해당 위치에 차가 있는지 없는지 확인
목록은 주차장에 자리 여부 출력
의 기능을 각각 수행한다.
import java.util.Scanner;
public class ArrayTest3 {
public static void main(String[] args) {
boolean[] car = new boolean[5]; // 차 5대들어가는 주차장
Scanner scan = new Scanner(System.in);
// 배열은 garbage 값이 들어 있지 않다.
// 그렇기 때문에 초기값으로 False가 들어있다.
// 배열에서는 0번째부터 index가 시작하나
// 사람에게는 1번째부터 index가 시작한다.
// 그렇기 때문에 사용자에게 보여줄 때는 index + 1 의 형태로 출력을 한다.
while(true) {
System.out.println("1. 입차 2. 출차 3. 목록 4. 끝");
int input = scan.nextInt();
if(input == 1) {
// 입차
System.out.println("입차할 위치를 입력해주세요 ");
int in = scan.nextInt();
if(car[in-1] == true) {
System.out.println(in + "번째 위치는 현재 주차가 불가합니다. ");
}else {
System.out.println(in + "번째 위치에 주차를 완료했습니다. ");
car[in-1] = true; // 입차 완료
}
}else if(input == 2) {
// 출차
System.out.println("출차할 위치를 입력해주세요 ");
int out = scan.nextInt();
if(car[out-1] == true) {
System.out.println((out-1) + "위치의 차를 출차합니다. ");
car[out-1] = false; // 출차
}else {
System.out.println("해당 자리에 주차되어있지 않습니다. ");
}
}else if(input == 3) {
// 목록
System.out.println("주차 목록");
for(int i = 0; i < car.length; i++) {
System.out.println((i+1) + "번쨰 위치 : " + car[i] );
}
}else if(input == 4) {
// 끝
break;
}
}
}
}
먼저 차 5대를 주차할 수 있는 배열 car를 boolean 타입으로 만든다.
배열은 garbage값이 들어 있지 않기 때문에 초기값으로 FALSE가 들어 있다.
배열을 입출력할 때 조심해야하는 것은
컴퓨터에겐 배열의 INDEX 값은 0부터 시작하지만
사람에게는 1부터 시작한다는 것이다.
그렇기 때문에 사람에게 입력받은 INDEX값은 부조건 -1 해주어야한다.
반대로 사람에게 보여줄 때는 +1을 한다.
사용자가 끝을 입력할 때까지 코드를 반복할 것이기 때문에 while문을 돌려준다.
사용자에게 보여줄 메뉴는 아래와 같다.
1. 입차 2. 출차 3. 목록 4. 끝
만약 사용자가 1번을 입력하면 입차를 한다.
먼저 입차 위치를 입력받고
입력받은 index-1이 true 값이 있다면 이미 차가 있다는 의미이므로 주차 불가 메세지를 띄운다.
반대로 false의 경우엔 비어있다는 의미이므로 주차를 하고 false값을 true값으로 바꾸어준다.
2번을 입력하면 출차이다.
사용자에게 출차위치를 묻고
사용자에게 받은 index-1 값이 true이면 제대로 차가 있다는 의미이므로 출차를 했다는 메세지와 함께
자리가 비었다는 false를 표시한다.
만약 false 값이면 차가 없다는 뜻이므로 주차가 되어 있지 않다는 메세지를 띄운다.
3번은 목록 출력이다.
car 배열의 길이만큼 for문을 돌려 그대로 출력해주면 된다.
4번 끝은
break를 통해 while문을 벗어나면 된다.
# 구구단 프로그램
구구단은 2단부터 9단까지
1부터 9까지 곱하는 식이다.
이를 위해서는 이중 for문을 사용해주어야한다.
이중 for문은 for문 안에 for문이 또 들어가 있는 것이다.
가장 바깥의 for문은 보통 행, 안쪽의 for문은 열을 위해 돌아간다.
class Gugudan2{
public static void main(String[] args){
int dan;
int i;
System.out.println("구구단");
for(i = 1; i <= 9; i++){
for(dan = 2; dan <= 9; dan++){
System.out.print(dan+"*"+i+ "=" + dan*i+"\t");
}
System.out.println();
}
}
}