열두 번째 수업

정혅·2024년 2월 23일

더 조은 아카데미

목록 보기
17/76

퀴즈 - 어제 복습 및 가위바위보 게임

  1. 사용자에게 값을 입력받아서 출력하기
class Practice{
    public static void main(String[]arg) {

        Scanner sc = new Scanner(System.in);
        String userName = null, userNum = null, userBirth = null, u1 = null;

        while(true) {
            System.out.println("선택하세요...");
            System.out.println("1. 데이터 입력");
            System.out.println("2. 프로그램 종료");
            System.out.print("선택 : ");
            u1 = sc.next();

            if(u1.charAt(0) == '1') {
                System.out.print("이름 : ");
                userName = sc.nextLine();

                System.out.print("전화번호 : ");
                userNum = sc.nextLine();

                System.out.print("생년월일 : ");
                userBirth = sc.nextLine();
                System.out.println("입력이 완료됐습니다.");

                PhoneInfo Info = new PhoneInfo(userName, userNum, userBirth);
                Info.printInfo();
                }
            else if(u1.charAt(0) == '2') {
                System.out.println("프로그램을 종료합니다.");
                break;
            }else System.out.println("잘못된 입력입니다.");
        }
  • 값이 무조건 잘못된 입력이라고 나왔는데 그 이유는 char로 내가 변환시켜서 숫자와 비교했는데, ' ' 이 작은 따옴표를 하지 않아서 무조건적으로 else로 가게된것이다.

  1. 가위바위보 게임 - Math.random() / switch case문을 이용
package com.test.blog;

import java.util.Scanner;

public class Practice2 {

    public static void main(String[] args) {
        int a = 1, b = 2;

        Scanner sc = new Scanner(System.in);

        System.out.println("가위바위보 게임을 시작합니다.!");
        System.out.println("하나의 숫자를 입력하세요.");

        while(true) {
            int ran = (int)(Math.random()*3)+1;//1~3난수 발생
            System.out.println();
            System.out.print("1번: 가위 / 2번: 바위 / 3번: 보 / 4번: 게임 종료 / 사용자 입력: ");
            int user = sc.nextInt();

            switch(user) {

            case 1:
                if(ran == user) {
                    System.out.println("비기셨습니다. 다시 입력하세요!");
                }else if(ran - user == a) {
                    System.out.println("이기셨습니다. 축하드립니다!!");
                }else if(ran - user == -a) {
                    System.out.println("지셨습니다. 다음에 또 도전하세요.");
                }else if(ran - user == b) {
                    System.out.println("지셨습니다. 다음에 또 도전하세요.");
                }else if(ran - user == -b) {
                    System.out.println("이기셨습니다. 축하드립니다!");
                }break;

            case 2:
                if(ran == user) {
                    System.out.println("비기셨습니다. 다시 입력하세요!");
                }else if(ran - user == a) {
                    System.out.println("이기셨습니다. 축하드립니다!!");
                }else if(ran - user == -a) {
                    System.out.println("지셨습니다. 다음에 또 도전하세요.");
                }else if(ran - user == b) {
                    System.out.println("지셨습니다. 다음에 또 도전하세요.");
                }else if(ran - user == -b) {
                    System.out.println("이기셨습니다. 축하드립니다!");
                }break;
            case 3:
                if(ran == user) {
                    System.out.println("비기셨습니다. 다시 입력하세요!");
                }else if(ran - user == a) {
                    System.out.println("이기셨습니다. 축하드립니다!!");
                }else if(ran - user == -a) {
                    System.out.println("지셨습니다. 다음에 또 도전하세요.");
                }else if(ran - user == b) {
                    System.out.println("지셨습니다. 다음에 또 도전하세요.");
                }else if(ran - user == -b) {
                    System.out.println("이기셨습니다. 축하드립니다!");
                }break;
            case 4:
                System.out.println("프로그램이 종료됩니다.");
                break;
            default: System.out.println("올바른 입력이 아닙니다. 다시 입력하세요 ㅠㅠ");
            }if(user == 4)break;
        }
    }
}
  • 예...비효율의 극치인거 저도 압니다잉... 배열을 선언해야하나 라고 생각한 시점이 다했을 때여서...전 문제 '' 안찍어서 출력이 제대로 안된 문제 다시 하느라 ..
정답
import java.util.*;

class FlowEx7 {
    public static void main(String[] args) { 
        int user, com;
        String[] str = {"가위", "바위", "보"};

        System.out.print("가위(1),바위(2), 보(3) 중 하나를 입력하세요.>");

        Scanner scanner = new Scanner(System.in);
        String tmp = scanner.nextLine(); // 화면을 통해 입력받은 내용을 tmp에 저장
        user = Integer.parseInt(tmp);    // 입력받은 문자열(tmp)를 숫자로 변환

        com = (int)(Math.random() * 3) + 1;  // 1,2,3중 하나가 com에 저장됨

        System.out.println("당신은 "+ str[user-1] +"입니다.");//배열의 0번째를 가르키기 위함 
        System.out.println("컴은  "+ str[com-1] +"입니다.");

        switch(user-com) {
            case 2: case -1:
                System.out.println("당신이 졌습니다.");
                break;
            case 1: case -2:
                System.out.println("당신이 이겼습니다.");
                break;
            case 0:
                System.out.println("비겼습니다.");
    //            break;        // 마지막 문장이므로 break를 사용할 필요가 없다. 
        }
    } // main의 끝
}
  • 내가한 메커니즘과 같은데, 배열을 이용하고, switch case문에서 저렇게 동시에 case문을 놓을 수 있는지 몰랐다..

  • switch~ case문의 조건을 여러개 하고싶다면 case ~ : case ~ : 형태로 놓으면 된다.


퀴즈 - 반복문을 이용해 369

내가 짠거..스터디때 했는데 왜 못한거지 33,36이런곳이 짝짝이 안나옴..
for(int i = 0; i < 100; i++) {
        if(i % 10 == 3 || i % 10 == 6 || i % 10 == 9) {
            System.out.println("짝\t");
        }else if(i / 11 == 3 || i / 11 == 6 || i / 11 == 9) {
            System.out.print("짝짝\t");        
            }else System.out.print(i + "\t");
        }
    }
정답
public static void main(String[] args) { 
    for(int i=1;i<=100;i++) {
        System.out.printf("i=%d ", i);
            int tmp = i;

            do {
                if(tmp%10%3==0 && tmp%10!=0) // tmp%10이 3의 배수인지 확인(0 제외)
                    System.out.print("짝");
            } while((tmp/=10)!=0);  // tmp /= 10은 tmp = tmp / 10과 동일

            System.out.println();
        }
    } // main
}

for 중첩 반복문 continue/break; 를 이용해 원하는 반복문 벗어나기 - Label

  1. 빠져나가길 원하거나 다시 시작하길 원하는 반복문 앞에 Label을 붙인다.

        Loop1 : for~ > 다음 줄로 넘어가서 반복문 선언 가능

  1. 중첩된 반복문 내부에서 break< label 명>; 또는 continue<label명>; 을 사용한다.

  2. 단, Label을 통해 이동하려면 break, continue보다 위에 선언되어 있어야한다.

for문을 빠져나가서 그 밑에 선언해놓은 for문으로 점프하고, 그런건x

일종의 변수이므로, 당연히 먼저 선언 되어있는 label로만 이동이 가능하다.

예시
public class LabelTest1 {

    public static void main(String[] args) {
        Loop1 : for(int i=2;i <=9;i++) {    
            for(int j=1;j <=9;j++) {
                if(j==5)
                    break Loop1;
                System.out.println(i+"*"+ j +"="+ i*j);
            } // end of for i
            System.out.println();
        } // end of Loop1
    }
}
  • Loop1로 break;시켰기 때문에 2단부터 9단까지 4를 곱한 값만 출력한다.
위 와 같지만 그냥 break;만 있을때
public class LabelTest2 {

    public static void main(String[] args) {
        Loop1 : for(int i=2;i <=9;i++) {    
            for(int j=1;j <=9;j++) {
                if(j==5)
                    break;
                System.out.println(i+"*"+ j +"="+ i*j);
            } // end of for i
            System.out.println();
        } // end of Loop1
    }
}
  • break;로 벗어나기 때문에 각 단의 5를 곱한값만 출력하지 않는다.

배열 개념

배열(Array)

  • 동일한 자료형의 순차적 자료 구조

  • 연관된 데이터를 모아서 관리하기 위한 데이터 타입

  • 변수 vs 배열 > 변수는 한 개의 데이터를 저장한다면, 배열은 여러 개의 데이터를 저장

특징

  • 인덱스 연산자 []를 이용하여 빠른 참조가 가능

  • 배열의 인덱스(index)는 0부터 시작

  • 물리적 위치와 논리적 위치가 동일

  • 자바에서는 객체 배열을 구현한 ArrayList를 많이 활용

다.

배열 선언 + 초기화(1)
int[] arr1 = new int[10];
int arr2[] = new int[10];

위와 같이 2가지로 선언할 수 있는데 1번 방법을 더 선호

new int[숫자] > 숫자는 배열의 길이를 뜻한다.

배열 선언 + 초기화(2)
  • 배열의 값을 나중에 추가하는 방법도 있지만, 선언하는 시점에 초기값을 설정하는 방법이 있다.

  • 배열을 초기화하지 않는다면 자료형에 따라 자동으로 초기화되는데, int > 0 / float > 0.0 / 객체 > null 로 자동 초기화된다.

int[] numbers = new int[]{10, 20, 30};//길이개수가능 생략
int[] numbers = {10,20,30}; //new int[]생략 가능 > 추천
int[] ids;
ids = new int[]{10, 20, 30};//선언 후 배열을 생성하는 경우는 new int[]생략할 수 없음
int[][] numArr = new int [2][3];
int[][] temp1;
temp1 = numArr;//가능 temp1은 numArr의 값과 같아진것
temp1[0][0]; //numArr[0][0] 과 같은 값을 가지게 된다.
int[] temp2;
temp2 = numArr; //오류 1차워 배열에 2차원 배열을 넣으려고 해서
temp2 = numArr[0]; //이런식이여야 가능
배열 선언 시 주의사항
  • 배열의 크기를 너무 크게 설정하면 불필요한 메모리가 낭비될 수 있다 > 사용할 만큼만 설정

  • 배열을 선언하면 개수만큼 메모리가 할당되지만, 실제 요소(data)가 없는 경우도 있다.

    • 아직 데이터가 몇 개 없는 상태라면, 배열의 길이와 요소의 개수는 동일하지 않다고 볼 수 있다.

    • length를 통해 for문을 돌릴 때 오류 주의해야한다.


1차원 배열 클래스 생성

반환 자료형은 꼭 int[] (배열의 자료형)으로 두어야한다. 반환되는 자료형도int로 동일해야한다.

class ArrayAndMethods
{                //int[] 배열의 자료형 들어가야한다 
    public static int[] addAllArray(int[] ar, int addVal)
    {
        for(int i=0; i<ar.length; i++)
            ar[i]+=addVal;//arr배열에 0부터4자리부터 7씩 더해진다.

        return ar;        
    }

    public static void main(String[] args)
    {
        int[] arr={1, 2, 3, 4, 5};
        int[] ref;

        ref=addAllArray(arr, 7);
        //arr이 위 int[] ar에 들어가고, addVal에 7이 들어간다.
        if(arr==ref)
            System.out.println("동일 배열 참조");
        else
            System.out.println("다른 배열 참조");

        for(int i=0; i<ref.length; i++)
            System.out.print(arr[i]+" ");
    }
}

퀴즈- 1차원 배열을 이용해 배열 속 최소값, 최대값 구하기

import java.util.Scanner;

class Question13_1
{
    public static int minValue(int[] arr)
    {
        int min = arr[0];
        for(int i=1;i<arr.length;i++)
            if(min>arr[i]) min = arr[i];
        return min;
    }
    public static int maxValue(int[] arr)
    {
        int max = arr[0];
        for(int i=1;i<arr.length;i++)
            if(max<arr[i]) max = arr[i];
        return max;
    }

    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        int[] arr = new int[5];

        System.out.println("숫자 " + arr.length + "개를 입력하세요.");
        for(int i=0;i<arr.length;i++)
            arr[i] = sc.nextInt();

        System.out.println("가장 작은 수는 " + minValue(arr));
        System.out.println("가장 큰 수는 " + maxValue(arr));
    }
}

2차원 배열(중)

예제 1
class TwoDimenArray
{
    public static void main(String[] args)
    {
        int[][] arr=new int[3][4];//[a][b]

        for(int i=0; i<3; i++)//[a]부분
            for(int j=0; j<4; j++)//[b]부분
                arr[i][j]=i+j;//각 값이 해당 주소에 값에 들어간다.

        for(int i=0; i<arr.length; i++)//수를 적는거 보다.length가 더 좋
        {
            for(int j=0; j<arr[i].length; j++)
                System.out.print(arr[i][j]+" ");

            System.out.println("");
        }
    }
}
배열적으로 보면

메모리맵상으로 보면

arr이 1000번지 주소값을 가지고 1000번지에 1차원 배열을 3개 저장할 수 있는length를 1000번지에 저장하고, 2000번지에 1차원 배열을 4개 저장할 수 있는 length0에 2000번지가 저장되고, [1]에는 배열 4개를 저장할 수 있는 3000번지를 저장하고, [2]에는 배열 4개를 저장할 수 있는 4000번지의 주소값이 저장된다.
int num = arr[2][0]; > [2][0]의 값인 2가 num에 들어간다.


예제 2
class PatiallyFilledArray
{
    public static void main(String[] args)
    {
        int[][] arr={//3개의 배열
            {1, 2},
            {3, 4, 5},
            {6, 7, 8, 9}
        };

        System.out.println("배열의 세로길이: "+arr.length);//arr의 length = 3 

        for(int i=0; i<arr.length; i++)
            System.out.printf("%d행의 길이: %d \n", i+1, arr[i].length);
    }
}
  1. 3개의 배열을 가지고 있는 1000번지가 생겨나고, arr에는 1000번지의 주소값이 들어간다.

  2. 1000번지 [0]에 2000번지이고, length가 2인 배열의 주소 들어가있고, 1000번지[1]에 3000번지 이고, length가 3인 배열의 주소 들어가있고, 1000번지[2]에 4000번지이고, length가 4인 배열의 주소가 들어가있다.

  3. arr[i].length하면 해당 배열에 들어있는 주소값의 length가 출력된다.


퀴즈1 - 1차원배열 값 증가시키는 메소드를 이용해 2차원 배열의 값 증가

내가 한것 - 정답 근
class Practice{

    public static void addOneDArr(int[] arr, int add) {

        for(int i = 0; i < arr.length; i++) {
            arr[i] += add;
        }
    }
    public static void addTwoDArr(int[][]arr, int add ) {
        for(int i = 0; i < arr.length; i++) {
            addOneDArr(arr[i], add);
        }
    }

    public static void main(String[]arg) {
        int[][] arr = {
                {1, 2, 3},
                {4, 5, 6},
                {7, 8, 9}
        };
        System.out.println("초기 2차원 배열" + arr);
        addTwoDArr(arr, 3);
       }
   }
  • 처음에 addTwoDArr 메소드에서 addOneDArr메소드를 호출하지않고, 코딩했고, 호출을 어떻게 하는지 고민했다..ㅠ

    • 이름 부르고 괄호안에 매개변수 값 넣으면 되는거였는데
  • 출력을 어떻게해야하는지 또 고민되어서 출력을 못넣었음

    • 그러나 대체적인 코딩 문장들은 맞았다.
정답
class Practice{

    public static void addOneDArr(int[] arr, int add) {
        //int[]arr > 1차원 배열을 받기 때문에 자료형이 같아야한다.
        for(int i = 0; i < arr.length; i++) {
            arr[i] += add;
        }
    }
    public static void addTwoDArr(int[][]arr, int add ) {
        for(int i = 0; i < arr.length; i++) {
            addOneDArr(arr[i], add);//arr의 0번째에 있는 주소값 > 1차원 배열
            //arr에 각 자리에 1차원 배열이 저장되어있는데, 그 1차원배열을 OneDArr로 보내주면서 호출
        }
    }

    public static void main(String[]arg) {
        int[][] arr = {
                {1, 2, 3},
                {4, 5, 6},
                {7, 8, 9}
        };
        System.out.println("초기 2차원 배열" + arr);
        //이렇게 출력하면 오류가 나는데, for문으로 2차원 배열 i, j해서 값 증감시켜서 하나씩 출력해야한다.
        addTwoDArr(arr, 7);

        for(int i = 0; i < arr.length; i++) {
            for(int j = 0; j < arr[i].length; j++) {
                System.out.println(arr[i][j]);
            }
            System.out.println();
        }
    }


퀴즈2 - 2차원 배열의 1차원 배열 순서를 바꿔라

class Practice{
    public static void addOneDArr(int[] arr) {
            for(int i = 0; i < arr.length; i++) {
                arr[i] = arr[];
            }
    }
    public static void addTwoDArr(int[][]arr) {
        for(int i = arr.length-1; i < arr.length; i--) {
            addOneDArr(arr[i]);
        }
    }

    public static void main(String[]arg) {
        int[][] arr = {
                {1, 2, 3},
                {4, 5, 6},
                {7, 8, 9}
        };
        addTwoDArr(arr);for(int i = 0; i < arr.length; i--) {
            for(int j = 0; j < arr[i].length; j++) {
                System.out.print(arr[i][j]);
            }
        System.out.println();

}
    }
}
  • 처음에는 출력할때 for문 이용해서 하려다가, 이 방법이 아닌것같고, 메소드를 만들라는 문제를 뒤늦게 봤다.

  • 메소드를 만들때 1차원 배열씩 해서 덮어써야할것같다는 생각이 들었으나, 그걸 어떻게 구현하는지 잘 모르겠어서 타임오바

정답
class Question13_2_2
{
    public static void arrShift(int[][] arr)
    {
        int[] lastRow = arr[arr.length-1];
        //덮어써서 옮기기 때문에 처음에 값을 지정 > 2니까 주소값 4000번지
        for(int i=arr.length-1;i>0; i--)
            arr[i] = arr[i-1];//이 코드를 통해 순서를 바꿔준다. 해당 자리 주소에 다른 주소값을 넣게끔 
        arr[0] = lastRow;
    }


    public static void main(String[] args)
    {
        int[][] arr = {//1000번
            {1, 2, 3}, //2000번지
            {4, 5, 6}, //3000번지
            {7, 8, 9} //4000번지 
        };

        arrShift(arr);
        for(int i=0;i<arr.length;i++)
        {
            for(int j=0;j<arr[i].length;j++)
            {
                System.out.print(arr[i][j] + "\t");
            }
            System.out.println();
        }
    }
}

for- each루프(굉장히 자주 쓰임)

  • arr배열이 for문 안에서 int e에 순차적으로 배열 값이 입력되어서 sum에서 합쳐지는데, int e:arr 로 arr배열의 객체 안에 있는 정보를 순차적으로 출력하는데 사용한다.

    예제3
class EnhancedFor
{
    public static void main(String[] args)
    {        
        int[] arr={1, 2, 3, 4, 5};//차원 배열

        int sum=0;
        for(int e: arr)//자동으로 순차적으로 입력 > 1, 2, 3,... 배열순서대로
            sum+=e;

        System.out.println("배열 요소의 합: "+sum);

        for(int e: arr)
        {
            e++;
            System.out.print(e+" ");
        }

        System.out.println("");
        for(int e: arr)//위와 마찬가지
            System.out.print(e+" ");
    }
}
예제5
class Number
{
	public int num;
	public Number(int num)
	{
		this.num=num;
	}	
	public int getNum()
	{
		return num;
	}
}

class EnhancedForInst
{
	public static void main(String[] args)
	{	
		Number[] arr=new Number[]{//1000번지 > length > 3
			new Number(2),//2000번지 객체 생성 num = 2
			new Number(4),//3000번지 객체 생성 num = 4
			new Number(8)//4000번지 객체 생성 num = 8
		};
		
		for(Number e: arr)//모두 Number의 주소값을 가지고 있기때문에 arr의 주소를 저장하려면 자료형이 Number이여야한다.
			e.num++;
		
		for(Number e: arr)//순차적으로arr객체 속 주소값이 들어간다
			System.out.print(e.getNum()+" ");
		
		System.out.println("");
		for(Number e: arr)
		{
			e=new Number(5);//여기서 e는 arr의 주소값이 순차적으로 들어가는데, 순차적으로 들어가고, > 객체가 생성되면 > 그 객체의 주소값을 가지게되는 순서다.  
            //객체를 새로 생성해 5000번지가 되고, num = 5 
			e.num+=2; //num에 더하기 2 
			System.out.print(e.getNum()+" ");
		}//이런식으로 생겨난 객체들은 그 객체의 주소값을 참조하는 변수가 없으므로, 나중에 가비지콜렉터로 삭제된다. 
		
		System.out.println("");
		for(Number e: arr)//2000번지부터 순차적으로 
			System.out.print(e.getNum()+" ");
	}
}
  • main메소드의 처음 for문 보면 처음 2000번지에 있는 num을 ++ 시키니까 3으로 변환되고, Number e: arr 이니까 순차적으로 값이 들어가니, 2000, 3000, 40000,번지의 주소값이 차례로 들어가고 각 주소의 num이 ++될것이다.

    • 식이 끝나면 e는 메소드내에서 사라진다.
  • main메소드의 두번째 for문 보면 위에서 변한 값들을 출력시키는 메소드다.


퀴즈 - for-each문을 활용해 최소값 최대값 구하기

내가한것 - 정답 우히히
package com.test.blog;

class Practice {
	public static int minValue(int[] arr) {
		int min = arr[0];
		for (int min1 : arr) {
			if (min > min1) {
				min = min1;
			}
		}
		return min;

	}

	public static int maxValue(int[] arr) {
		int max = arr[arr.length - 1];
		for (int max1 : arr) {
			if (max < max1) {
				max = max1;
			}
		}
		return max;
	}

	public static void main(String[] args) {
		int[] array = { 1, 2, 3, 4 };
		System.out.println("최소값은 " + minValue(array));
		System.out.println("최대값은 " + maxValue(array));
	}
}


퀴즈 2 - 2차원 배열을 for each문을 이용해 출력하시오

내가한것, 맞게 했지만 두번씩 출력되었다...
class Practice{
	public static void main(String[] args) {
		int[][] array = {
					{10, 20, 30},
					{40, 50, 60}
					};
		for(int[] a : array) {
			for(int i = 0; i < array.length; i++)
			System.out.println(Arrays.toString(array[i]));                                  
		}
	}
}
내가한것, 정답은
class Practice{
	public static void main(String[] args) {
		int[][] array = {
					{10, 20, 30},
					{40, 50, 60}
					};
		for(int[] a : array) {//1차원 배열을 담아야하니까 1차원배열의 변수로 선언해야한다.
			System.out.println(Arrays.toString(a));
		}
	}
}
  • Arrays.toString 은 배열을 문자열로 변환해주는데, 내가 굳이 for문을 이용해서 배열을 돌리려고해서 그렇다. 어차피 차례로 들어오는데 for문을 이용해서 두번 돌린것

  • for-each로 들어오는 int[]a 로 값을 출력하면 된것이다.

원래 정답(선생님 ver)
for(int[] arr:num){
 	for(int n : arr)
 		{
 			System.out.print(n + "\t");
 		}
 		System.out.println();
  • 2차원 배열이였던 것을 1차원 배열로 옮겨서 다시 int형 변수안에 넣어 차례로 출력해준다.

cmd를 이용해서 for each이용해서 배열에 값 넣기

  • 저렇게 치고 엔터하면 AAA BBB CCC 출력되는 형태다.

Day12 - Google Drive

기본 개념 다시 살펴보기

  • 인스턴스가 먼저 초기화되는지, 클래스가 먼저 초기화되는지

0개의 댓글