[JAVA.09] 배열(array) 그리고 향상된 for문🕊

Kama_Code·2023년 7월 13일
1

JAVA

목록 보기
14/20
post-thumbnail
post-custom-banner
  • 어떤 한 프로그램이 있다.
    1+1= 2 만 계산할 수 있는 프로그램이라면 아무도 사용하지 않을 것이다.
    하지만 다양한 수를 계산하는 프로그램이라면 사용할 것이다.
    배열도 마찬가지다. 하나만 다루는 것이라면 그리
    효율이 좋지 못한 프로그램이 될 것이다. 그래서 개인적으로 배열을 통해
    다수의 데이터를 효과적으로 다루는 경우가 많다.

<Step.1> 1차원 배열

  • 1차원 배열: 타입이 같은 둘 이상의 데이터를 저장할 수 있는
    1차원 구조의 메모리 공간을 말한다.
  • 배열도 메소드(함수)의 매개변수를 통해 다른 메소드(함수)를 호출할 때 전달할 수 있다.
  • 랜덤 생성하기 : Random random = new Random();
    ㄴmath.random -> 0~1사이의 실수를 랜덤 반환하는 메소드다.
  • 위 사진에서 korScore은 주소값(참조값)으로 stack 영역에 저장되며,
    new, 배열, 스트링은 heap 영역에 저장된다.
  • 배열은 인덱스가 항상 0부터 시작한다.
    ( 0번째가 1번째라는 것이다. ) - 이것을 주의해야 한다.
  • 배열에 초기값을 넣을 때는 아래 사진과 같이 선언한다.

<Step.2> main() 메소드의 매개 변수

  • 메인 메소드도 매개변수를 설정해줄 수 있다.
  • 상단 메뉴 - run - run configurations

<Step.3> call by 호출

  • 매우 중요한 내용이다.
  1. Call by value(값에 의한 호출)
    ㄴ스택영역만 사용하는 호출방식이다.
    ㄴ파라미터(인수)가 전달될때 메모리의 복사를 통해 값 전달
    ※ 쉽게 말해서 메인 메소드에서 A 라는 이름을 가진 메소드를 호출하고
    int 자료형 값을 복사해서 보낸다. (하지만 서로 다른 영역이고 복사한 값이 들어가므로
    변수의 값에 실제 영향을 미치지 않는다)
    int형 -> 스택 영역 저장 // 배열 arr -> 힙 영역에 저장
  • main의 first = 100과 sencond = 200이 복사하여
    callbyValue 메소드의 매개변수 fNum과 sNum에 들어간다.
  • 매우 중요한 내용이다.
  1. Call by reference(참조에 의한 호출)
    ㄴ값이 아닌 객체의 참조값(주소값)을 전달한다
    ㄴ스택영역과 힙영역을 동시에 사용하는 호출방식이다.
    ㄴ매개변수가 전달될때 객체의 참조값(주소)이 전달
    ㄴ참조값이 복사되어 전달되는 방식이므로 서로 다른 지역의 메소드에서
    동일한 객체를 참조하게 됨
    ㄴJAVA에서 객체를 다루는 일반적인 방식이다.

<Step.4> for ~ each 문 (향상된 for문)

  • 배열을 이용한 반복문을 사용하다 보면 for문 안에 항상 배열의 길이만큼
    반복을 하는 코드를 작성하게 된다.
  • 배열의 일부가 아닌 전체를 참조할때 주로 사용되는 for문이다.
    코드가 짧고 간결하여 빈번히 사용된다.
  • 배열의 원소를 참조의 형태로 가져와서 사용한다.
    따라서 참조의 목적으로만 사용해야하고, 값의 변경은 허용하지 않는다.
    ( 통째로 복사될 뿐이므로.. )
  • 형식]
    for(자료형 참조변수 : 배열명(주소값을 확인한다){
    실행문장;
    참조변수를 통해 배열의 원소 출력가능함;
    ㄴ하나씩 확인한다.
  • 향상된 for문은 복사해서 보는 것

<Step.5> 2차원 배열

  • 2차원이란 말이 들어가면 평면(2d)를 생각하는 것이 좋다.
    ㄴ자연스럽게 행열(가로축, 세로축)을 떠올려주는 것이 TIP이다.
  • 2차원 배열의 초기값은 이렇게 넣어준다. (초기화를 해준다)
  • 2차원 배열의 초기화 주의사항이 있다.
  1. 공간이 있을 경우 - 자연스럽게 0으로 채워주지만
  2. 아래처럼 자리(공간)이 없을 경우 - null로 들어가게 된다.
    여기서 0과 null은 완전히 다르다.
    ▶ 0은 숫자라서 추후 값을 넣을 수 있지만 null은 공간 자체가 없어서
    별도의 공간을 만들어줘야 숫자가 들어갈 수 있다.

<Step.6> 배열에 관련된 유틸리티 메소드

  • [ java.util.Arrays 클래스에 정의되어 있는 메서드 ]
    원하는 값으로 배열 전부 또는 일부를 채울 때 사용하는 메서드

[해석] fill :
public static void fill(int[] a, int val)

→ 두 번째 인자(int val)로 전달된 값으로 배열 초기화

public static void fill(int[] a, int fromIndex, int toIndex, int val)
→ 인덱스 fromIndex ~ (toIndex-1)의 범위까지 val의 값으로 배열 초기화
: (toIndex-1)인 이유는 배열은 인덱스 시작이 0부터 시작하기에..

  • [ java.util.Arrays 클래스에 정의되어 있는 메서드 ]
    원하는 값으로 배열 전부 또는 일부를 채울 때 사용하는 메서드

[해석] copyOf :
public static int[] copyOf(int[] original, int newLength)

→ original에 전달된 배열을 첫 번째 요소부터 newLength 길이만큼 복사

public static int[] copyOfRange(int[] original, int from, int to)

→ original에 전달된 배열을 인덱스 from부터 to 이전 요소까지 복사

  • [ java.util.Arrays 클래스에 정의되어 있는 메서드 ]
    한 배열에 저장된 값을 다른 배열에 복사할 때 사용하는 메서드

[해석] arraycopy :

public static void
arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

→ 복사 원본의 위치 : 배열 src의 인덱스 srcPos
→ 복사 대상의 위치 : 배열 dest의 인덱스 destPos
→ 복사할 요소의 수 : length

  • 비교 및 정렬을 해주는 메소드도 있다

배열을 비교해주는 equals() 메서드가 있다.

equals()는 배열 안에 내용을 비교해주는 메소드이다.
boolean 조건은 두 배열에 저장된 데이터의 수, 순서 그리고
내용이 같을 때 true를 반환한다.
(배열 길이가 다르면 false를 반환한다.)

ex) A컵에 담긴 내용물 오렌지 주스를 비교

배열을 정렬해주는 sort() 메서드가 있다.

public static void sort(int[] a)
→ 매개변수 a로 전달된 배열을 오름차순으로 정렬

<Step.7> 정렬

★ 버블 정렬 내용보기

★ 삽입 정렬 내용보기

★ 선택 정렬 내용보기

<Step.8> 발전을 위한 문제풀이 (kama_code 출제)

  1. 길이가 5인 int형 배열을 선언해서 사용자로부터 5개의 정수를 입력받는다.
    그리고 최대값, 최소값, 모든 수의 합을 구하라. 함수(최대,최소,합)를 정의하여 구현하시오.
  2. 길이가 10인 배열을 선언하고 총 10개의 정수를 입력받아서 홀수와 짝수를
    구분해서 출력하시오.
  3. 과목 이름을 입력받아 해당 과목 점수를 출력해주는 프로그램을 작성해보자.
    없는 과목을 입력하면 "입력한 과목"은 없는 과목입니다.를 출력하면서
    무한반복을 하다가 "그만"을 입력받으면, 프로그램이 종료된다.
  4. String 2차원 배열을 이용하여 자바 용어 맞추기 게임을 만들어라!
    정답이면 정답입니다. 오답이면 틀렸습니다. 정답은 ~입니다 라고 출력되어야 한다.
  5. 주민등록번호 번호를 입력 받아 char 배열에 저장한 후 출력하세요.
    단, char 배열 저장 시 성별을 나타내는 숫자 이후부터 * 로 출력하세요
  6. 좌석 예약 프로그램을 만드시오.
    예약 완료 후, 같은 자리를 다시 예약하려고 할 때
    예약이 불가하다는 메세지와 함께 남아있는 좌석의 목록도 출력해야 합니다.
  7. 숫자야구게임을 만드시오.
  • 1~9 사이의 중복되지 않는 3개의 정수를 생성한다.
  • 사용자는 3개의 숫자를 입력한다.
  • 생성된 3개의 숫자를 맞추는데 위치까지 정확히 맞춰야 한다.
  • 숫자와 숫자의 위치까지 일치하면 strike 로 판정한다.
  • 숫자는 맞지만 위치가 틀렸다면 ball 로 판정한다.
  • 숫자3개가 모두 일치하지 않으면 out 으로 판정한다.
  • 3 strike 가 되면 게임은 종료된다.
  • 시도한 횟수를 표시한다.
  • 계속할지 종료할지 여부를 물어보고 다음 진행을 한다.

★ 정답 및 해설 ☆

  1. 중요한 점은 입력을 받는 기능, 배열 안에서 최대값, 최소값, 합을 구하는 메소드를
    잘 만들어서 잘 부르는 것이다. 자세한 해설은 아래에서
public class ArrayOne
{
	public static void main(String[] args)
	{
		/*
		1. 길이가 5인 int형 배열을 선언해서 사용자로부터 5개의 정수를 입력받는다.
		그리고 최대값, 최소값, 모든 수의 합을 구하라. 함수(최대,최소,합)를 정의하여 구			현하시오.
		*/
		System.out.println("5개의 정수를 입력해주세요: "); // 안내 메세지
		Scanner scan = new Scanner(System.in); // 사용자로부터 입력값을 받음
		int[] arr = new int[5]; // int형 배열 5칸 생성
		
		for (int i=0; i<5; i++) // 배열의 내용을 확인하기 위한 반복문
		{
			arr[i] = scan.nextInt(); // 전체 베열 scan에 저장함
		}
		System.out.println("======================"); // for문이 끝나면 출력되게 함
		System.out.println("최대값은 : " + maxN(arr));
		System.out.println("최소값은 : " + minN(arr));
		System.out.println("모든수의 합 : " + sum(arr));
		System.out.println("======================");
	}

	public static int sum(int[] arr) // 합계를 출력하는 메소드
	{
		int num = arr[0]; // 지역변수를 사용하기 위해 num을 초기화 시킨다.
		for(int i=0; i<5; i++)
		{
			num += arr[i]; // 누적해서 더해간 것을 반환
		}
		return num;
	}

	public static int minN(int[] arr)
	{
		int num = arr[0]; // 지역변수를 사용하기 위해 num을 초기화 시킨다.
		for (int i=0; i<5; i++)
		{
			if(num > arr[i]) // 배열을 비교해서 작은 것을 minN 메소드에 num에 넣어 반환 
			{
				num = arr[i];
			}
		}		
		return num;
	}

	public static int maxN(int[] arr)
	{
		int num = arr[0]; // 지역변수를 사용하기 위해 num을 초기화 시킨다.
		for (int i=0; i<5; i++)
		{
			if(num < arr[i]) // 배열을 비교해서 큰 것을 maxN 메소드에 num에 넣어 반환 
			{
				num = arr[i];
			}
		}
		return num;
	}
}

  1. 정수 10개를 입력받아 홀수 짝수를 구분하는 간단한 프로그램이지만
    보기 좋게 선을 넣고 안내를 하기 위해 잘 생각하고 흐름을 놓치지 말고 따라가야 한다.
    특히 배열은 반복문과 굉장히 친하다.
    ※ 배열하면? -> 반복문하고 친구지! 라고 기억하면 좋다
    왜냐하면 배열은 여러개의 데이터가 들어가 있는데 그 전체를 탐색하기 위해선
    반복문으로 탐색하는 것이 필수이기 때문이다.
public class ArrayTwo
{
	public static void main(String[] args)
	{
		/* 
			2. 길이가 10인 배열을 선언하고 총 10개의 정수를 입력받아서 홀수와 짝수를
			구분해서 출력하시오.
		 */
		
		Scanner scan = new Scanner(System.in); // 사용자로부터 정수를 입력받는다
		int[] arr = new int[10]; // 정수 int형 10개 숫자가 들어갈 수 있는 배열 생성
		System.out.println("정수 10개를 입력하시오: ");
		for(int i=0; i<10; i++) // 전체 배열을 확인한다 (반복문으로)
		{
			arr[i] = scan.nextInt(); //(사용자가 입력한 값을 arr배열에 저장한다.)
			
		}
		System.out.println("========================"); // 보기 좋게 구분하기 위한 선
		System.out.print("나는 홀수: "); // 홀수 안내하기 위한 문자열 (for문 밖에다 만듬)
		for(int i=0; i<10; i++) // 전체 배열을 다시 확인한다 (반복문으로)
		{
			if(arr[i] % 2 == 1) // 홀수의 조건: 2로 나누었을때 나머지가 1
			{
				System.out.print(arr[i] + " "); // 연속되어 입력하기 위해 print로 사용 후 스페이스바
			}
		}
		System.out.println(" "); // 한줄 띄기 위한 공백
		System.out.println("========================"); // 보기 좋게 구분하기 위한 선
		System.out.print("나는 짝수: "); // 짝수 안내하기 위한 문자열 (for문 밖에다 만듬)
		for(int i=0; i<10; i++) // 전체 배열을 다시 확인한다 (반복문으로)
		{
			if(arr[i] % 2 == 0) // 짝수의 조건: 2로 나누었을때 나머지가 0
			{
				System.out.print(arr[i] + " "); // 연속되어 입력하기 위해 print로 사용 후 스페이스바
			}
		}
		System.out.println(" "); // 한줄 띄기 위한 공백
		System.out.println("========================"); // 보기 좋게 구분하기 위한 선
	}
}
  1. 배열을 생성하여 그냥 무한반복만 돌려주면서 점수만 출력해주는 프로그램은
    간단하고 쉽다.
    하지만 프로그래밍 세계에서 이런 말이 있다.
    "좋은 프로그램과 개발자의 고생은 비례한다."

더 친절하게 더 편리한 프로그램을 만들기 위해선 더 섬세해야 한다.
어떤 부분은 반복을 하고 반복문 안에서도 어떤 부분은 반복을 하지 않고
1번만 출력하여 다시 처음으로 돌아가여 물어보는 프로그램은
단순한 프로그램보다 당연히 훨씬 어렵다.
아래 필자가 직접 짠 코드를 잘 읽어보고 흐름을 반드시 눈에 읽혀보자!

public class ArrayThree
{
	public static void main(String[] args)
	{
		/*
		3. 과목 이름을 입력받아 해당 과목 점수를 출력해주는 프로그램을 작성해보자.
		없는 과목을 입력하면 "입력한 과목"은 없는 과목입니다.를 출력하면서
		무한반복을 하다가 "그만"을 입력받으면, 프로그램이 종료된다.*/
		
		System.out.println("점수를 조회할 과목명을 입력하세요: ");
		//문자열 형태 subject 배열 목록
		String[] subject = {"국어", "영어", "수학", "사회", "과학", "도덕"}; 
		//int 정수 형태 score 배열 목록
		int[] score = {80, 81, 94, 56, 14, 25};
		Scanner scan = new Scanner(System.in); // 입력값 받기
		
		while(true) // 무한반복하면 while을 떠올려라!
		{		
			String input = scan.next(); // 입력한 값을 input이란 문자열 형태로 저장
			for(int i=0; i<subject.length; i++) // subject 배열 길이만큼 반복 탐색
			{				
				if (subject[i].equals(input)) // subject 안의 문자열이 입력한 문자열과 일치할 경우
				{
					//그 배열의 i번째과 score배열의 i번쨰 내용을 출력
					System.out.println(subject[i]+"의 점수는? " + score[i]+"점!");

				}						
			}  
			// 반복 출력되지 않도록 for문 밖에다가 적는다
			// subject의 배열 내용인 input 그리고 그만이 아닐경우(!) 
			if (!(Arrays.asList(subject).contains(input)) && (!(input.equals("그만"))))
			{
				// 출력!
				System.out.println(input + "은(는) 없는 과목입니다.");	
			}
	        if (input.equals("그만")) // 그만이면
	        {
	        	System.out.println("프로그램이 종료됩니다.");	
	        	scan.close(); // 사용자 입력값 그만 받기(프로그램 끄기!!)
	            break;
	        }
	       
		}	
	}
}
  1. 역시 이번에도 흐름이 중요하다.
    순서대로 생각한 흐름을 1~5번까지 주석으로 적어두었다.
오랜만에 나온 printf 
%d는 정수를 의미한다. %s는 문자열(string)을 의미한다.
,(쉼표) 다음으로 순서대로 들어갈 자리를 적어주는 것이다.

javas[i][0]은 첫번째 문제라면 javas[1][0]의 문제가 출력될 것이다.
if (good.equals(javas[i][1]))는 good이라는 입력한 값과
javas[i][1] : 정답이 똑같은지 다른지 판별하는 조건이다.

public class ArrayFour
{
	public static void main(String[] args)
	{
		/*
		 * 4. String 2차원 배열을 이용하여 자바 용어 맞추기 게임을 만들어라! 정답이면 정답입니다. 오답이면 틀렸습니다. 정답은 ~입니다
		 * 라고 출력되어야 한다.
		 */
		// 1. 문제와 정답이 담긴 2차원 배열 생성
		String[][] javas = { { "프로그램에서 사용되는 데이터 유형(data type)", "자료형" }, { "변수의 아무것도 안들어간 더미데이터(빈 데이터)", "null" },
				{ "힙 영역의 값을 호출하기 위해 객체의 메모리 위치의 어떤 것을 찾아야 할까?(ㅈㅅㄱ)", "주소값" }, { "데이터가 저장되는 메모리의 기억장소에 붙인 이름", "변수" },
				{ "메소드 안에서 선언되어 메소드 안에서만 사용되는 변수", "지역변수" }, { "데이터를 전달하면서 메소드를 호출할 때 전달 데이터를 저장할 변수", "매개변수" },
				{ "데이터 저장을 위한 메모리 공간을 확보해달라고 가상머신에게 부탁하는 행위", "변수선언" }, { "변수 선언 이후 처음으로 데이터를 저장하는 행위", "초기화" },
				{ "조건문이 true일때만 실행(?문)", "if문" }, { "변수값이 설정한 데이터가 같을때 실행(?문)", "switch문" },
				{ "true면 다음, false면 주로 한정된 반복문 탈출(?문)", "for문" }, { "조건식이 true면 실행, false면 주로 무한반복문 탈출(?문)", "while문" },
				{ "일단 실행구문 수행하고 조건식 true면 반복, false면 탈출(?-?문)", "do-while문" },
				{ "배열객체참조변수 안에 데이터를 저장하고 실행구문 반복(?-?문)", "향상된-for문" },
				{ "조건식이 false면 반복진행, true면 실행구문 계속 실행하지 않고 반복문 탈출", "break" }, { "강제로 다음 반복 구문으로 건너뜀", "continue" },
				{ "패시브! 클래스가 객체화가 되어야 속성변수가 메소드가 호출한 실행구문이 이루어짐", "생성자" }, { "행동! 실행구문을 대표하는 방법 이름(ㅔㅗㅡ)", "메소드" },
				{ "클래스를 실행하면 메모리 공간(Heap)으로 올라간다. 같은말로 인스턴스", "객체" }, { "메소드 실행 후에 아무런 값도 반환하지 않는다.", "void" },
				{ "메소드 실행을 중지하고 데이터를 호출한 곳으로 반환하라.", "return" }, { "클래스가 소유한 고유멤버(속성변수, 메소드, 생성자)를 지칭", "this" },
				{ "클래스의 특성 중 정보 은닉을 가장 잘 보여주는 메소드(영어/영어)", "getter/setter" },
				{ "같은 이름의 생성자를 2개 이상 정의하는 것(한글로)", "오버로딩" }, 
				};
		// 2. 사용자로부터 입력값을 받는다.
		Scanner scan = new Scanner(System.in);

		// 3. 만든 배열의 전체를 탐색한다.
		for (int i = 0; i < javas.length; i++)
		{
			System.out.printf("문제%d] %s 는 무엇일까요? ", i + 1, javas[i][0]);
			// 4. 사용자로부터 입력값을 저장한다.
			String good = scan.nextLine();

			// 5. 정답인지 틀렸는지 판별한다
			if (good.equals(javas[i][1]))
			{
				System.out.printf("대단한데요~? 정답입니다!%n%n");
			} 
			else 
			{
				System.out.printf("아쉽게도 틀렸어요! 정답은 [%s]입니다.%n%n", javas[i][1]);		
			}			
		}
		scan.close();
	}
}
  1. 주민번호를 입력받아 성별 이후는 마스킹으로 변환하는 코드이다.
    핵심은 아래와 같다.

1] char[] bunho = new char[jumin.length()];
사용자의 입력한 값의 길이만큼 배열에 담는 것!
2] if(i >= 8) 인덱스0부터 시작해서 성별 다음에 오는 번째를 계산하여 참을 만드는 것
3] bunho[i] = jumin.charAt(i); 그 외는 chatAt을 이용해서 하나하나 값을 넣는 것
ㄴcharAt(0)이라면 문자열의 0번째 문자를 char타입으로 변환

public class ArrayFive
{
	public static void main(String[] args)
	{
		/*
		5.주민등록번호 번호를 입력 받아 char 배열에 저장한 후 출력하세요.
		단, char 배열 저장 시 성별을 나타내는 숫자 이후부터 * 로 출력하세요.*/
		
		// 1. 사용자로부터 입력값 받기
		Scanner scan = new Scanner(System.in);
		
		// 2. -를 포함한 주민등록번호 입력받기
		System.out.println("주민등록번호 입력해주세요(-포함): ");
		// 3. 문자열 형태의 jumin 변수에 입력값을 저장
		String jumin = scan.nextLine();
		// 4. char 배열인 변수 bunho에 입력값만큼 하나하나 배열에 담기
		char[] bunho = new char[jumin.length()];
		
		// 5. 반복문 밖에서 출력된 결과 첫 안내
		System.out.print("변환된 주민번호: ");
		// 6. 출력하기 위한 char 배열 탐색
		for (int i=0; i<bunho.length; i++)
		{
			// 7. 성별 다음번째부터 *로 바꿔준다.
			if(i >= 8)
			{
				//8. 성별 번쨰부터 *을 반복해서 바꿔준다.
				bunho[i] = '*';
			}
			// 8. 그 외는 char[] 변수에 담긴 문자를 출력한다.
			else
				bunho[i] = jumin.charAt(i);
			// 9. 총 결과는?
			System.out.print(bunho[i]);
		}
		scan.close(); // 입력을 그만 받는다.
	}
}
  1. 좌석 예약 프로그램이다.
    엄청나게 중요한 코드이다.
    10x10인 2차원 배열을 생성한 후
  • 공간을 만들어주었다면 자바는 자동으로 그 안에 값을 0으로 채워준다는 특성이 있다는 것!

    그래서 이 특성을 이용하여 0일 경우 빈좌석으로 생각하여 예약을 할 수 있는
    프로그램을 만들 수 있는 것이다.

또 배열은 인덱스 0번째부터 시작한다는 사실!

  • 사람은 첫번째 두번째 순으로 말하지만
  • 배열은 0번째 첫번째로 하나가 밀리게 된다.
    → 우리가 말하는 기준을 자바 순번으로 바꿀땐 -1
    → 자바가 말하는 기준을 우리 순번으로 바꿀땐 +1을 해주어야 한다.
public class ArraySix
{
	public static void main(String[] args)
	{
		/*
		 * 6. 좌석 예약 프로그램을 만드시오. 예약 완료 후, 같은 자리를 다시 예약하려고 할 때 예약이 불가하다는 메세지와 함께 남아있는 좌석의
		 * 목록도 출력해야 합니다.
		 */
		// 1. 사용자로부터 입력값을 받는다.
		Scanner res = new Scanner(System.in);

		// 2. 총 좌석을 만든다.10x10의 100석이다.
		int[][] seat = new int[10][10];
		// 3. 입력한 값을 행열에 저장하기 위해 2개의 int형 변수를 선언한다.
		int x, y;
		// 4. 총 좌석수는 100석이다.
		int full = 100;

		// 5. 좌석이 있다면 무한 반복한다.
		while (full > 0)
		{
			System.out.println("[총 100석] 예약할 좌석 '(행 열)'로 입력: ");
			x = res.nextInt(); // 행을 입력한 값 저장
			y = res.nextInt(); // 열을 입력한 값 저장

			// 6. 존재하지 않는 좌석 입력시 걸러내기
			if (x > 10 || x < 1 || y > 10 || y < 1)
			{
				System.out.println("▶ 존재하지 않는 좌석입니다. \n▷ 1행 2열 예약시 '1 2'를 입력해주세요!)");
				continue;
			}
			// 7. 자바의 매우 중요한 특성: 배열 생성하여 공간만 만들어주면 자동으로 전부 0으로 채워준다
			// 그 특성을 이용해서 입력한 번째의 배열이 0일 경우 빈 좌석이 된다.
			// 입력한 값에 -1을 해주는 이유는 배열의 인덱스는 0번부터 시작하며 우리는 1번째부터 부르기 때문이다.
			// 10인 배열을 생성해주면 0~9까지가 생성되며, 우리는 1~10까지로 부르는 차이때문에 -1을 해준다.
			if (seat[x - 1][y - 1] == 0)
			{
				System.out.println("성공적으로 예약이 완료되었습니다.");
				// 8. 예약되었으니 0에서 1로 채워준다.
				seat[x - 1][y - 1] = 1;
			} else
			{
				System.out.println("이미 예약된 좌석입니다.");
				System.out.print("↓ 비어있는 좌석 ↓");
				// 9. 좌석의 행을 전체 탐색한다.(배열은 인덱스 0번째부터 시작)
				for (int i = 0; i < 10; i++)
				{
					// 10. 좌석의 열을 전체 탐색한다.(배열은 인덱스 0번째부터 시작)
					for (int j = 0; j < 10; j++)
					{
						// 11. 좌석의 행열이 빈 좌석이라면?
						if (seat[i][j] == 0)
						{
							// 12. 배열의 0번쨰를 우리는 1번째로 말하므로 +1을 해준다.
							System.out.printf("\n→ %d행 %d열\n", i + 1, j + 1);
						}
					}
				}
			}
		}
	}
}
  1. 해당 게임의 핵심은 모든 기능을 하나하나
    모든 경우의 수를 따져서 만들어줘야 한다는 것이다.
    무한반복 while문 2개를 겹쳐서 게임중 게임 상태를 벗어나지 않도록 했다.
public class ArraySev
{
	public static void main(String[] args)
	{
		/*
		7. 숫자야구게임을 만드시오. 
		 + 1~9 사이의 중복되지 않는 3개의 정수를 생성한다. 
		 + 사용자는 3개의 숫자를 입력한다. 
		 + 생성된
		 + 3개의 숫자를 맞추는데 위치까지 정확히 맞춰야 한다. 
		 + 숫자와 숫자의 위치까지 일치하면 strike 로 판정한다. 
		 + 숫자는 맞지만 위치가 틀렸다면 ball 로 판정한다. 
		 + 숫자3개가 모두 일치하지 않으면 out 으로 판정한다. 
		 + 3 strike 가 되면 게임은 종료된다. 
		 + 시도한 횟수를 표시한다. 
		 + 계속할지 종료할지 여부를 물어보고 다음 진행을 한다.
		*/
		
		// 1. 랜덤을 생성하며 사용자로부터 입력값을 받는다.
		Random random = new Random();
		Scanner scanner = new Scanner(System.in);

		// 2. 게임에서 사용할 변수(첫게임, 2게임, 3게임 변수)
		int com1, com2, com3;
		int user1, user2, user3;
		int randomCnt = 0;// 난수생성 카운트
		int gameCount = 0;// 게임 카운트
		int strikeCnt = 0, ballCnt = 0;// 스크라이크,볼 카운트

		// 3. 게임을 전체 무한 반복
		while (true)
		{
			// 3. 게임을 전체 무한 반복2
			while (true)
			{
				// 4. 몇번째 게임인지 카운트 체크
				randomCnt++;

				// 5. 첫~세번째 게임의 1~9사이의 난수생성
				com1 = random.nextInt(100) % 9 + 1;
				com2 = random.nextInt(100) % 9 + 1;
				com3 = random.nextInt(100) % 9 + 1;
				if (!(com1 == com2 || com2 == com3 || com3 == com1))
				{
					// 6, 중복되지 않아야만 탈출하게끔 가두는 if문 조건 
					break;
				}
			} //// while end

			// 7. 컴퓨터 정답: 회차 + 첫게임 + 2게임 + 3게임 구분 출력(실게임에선 지워야함)
			System.out.println(randomCnt + "회:" + com1 + " " + com2 + " " + com3);

			while (true)
			{
				// 8. 사용자로부터 3게임의 정수를 저장한다.
				System.out.println("3게임의 정수를 입력하세요(1~9)");
				System.out.println("스페이스로 구분하며 마지막에 Enter를 눌러주세요");
				user1 = scanner.nextInt();
				user2 = scanner.nextInt();
				user3 = scanner.nextInt();

				// 9, 게임카운트 1회 증가
				gameCount++;

				// 10. 스크라이크 모든 경우(숫자와 위치까지 일치해야만 정답)
				if (com1 == user1)
					strikeCnt++;
				if (com2 == user2)
					strikeCnt++;
				if (com3 == user3)
					strikeCnt++;

				// 11. 볼의 모든 경우(숫자는 일치하나 위치가 다를때)
				if (com1 == user2 || com1 == user3)
					ballCnt++;
				if (com2 == user1 || com2 == user3)
					ballCnt++;
				if (com3 == user1 || com3 == user2)
					ballCnt++;

				// 12. 승리로 종료 선언
				if (strikeCnt == 3)
				{
					System.out.println("홈런!!~~~");
					System.out.println(gameCount + "번만에 홈런을 쳤습니다.");
					break;// 루프탈출
				} 
				else // 그외의 경우
				{
					// 13. 하나도 못맞추는 경우
					if (strikeCnt == 0 && ballCnt == 0)
					{
						System.out.println("아웃입니다");
					} 
					else // 14. 그 외를 출력해준다.
					{
						System.out.printf("%d 스트라이크, %d 볼\n", strikeCnt, ballCnt);
					}
					// 15. 스트라이크, 볼 카운트 초기화
					strikeCnt = 0;
					ballCnt = 0;
					// continue문은 필요없음.
				}
			} //// while end

			//16. 게임이 끝났다면 나오는 출력문
			System.out.println("한게임 더 하시겠습니까?(0:종료,1:재시작)");
			int restart = scanner.nextInt();
			if (restart == 0)
			{
				// 17. 게임종료
				System.out.println("\n==게임이 종료되었습니다.==\n");
				// 실행되는 즉시 main함수가 종료된다.
				System.exit(0);
			} 
			else if (restart == 1)
			{
				// 18. 게임을 재시작하기 위해 카운트변수 초기화
				strikeCnt = 0;
				ballCnt = 0;
				gameCount = 0;
				System.out.println("\n==게임을 재시작합니다.==\n");
			}
		} // 게임 전체 반복 while end
	}// main 메서드 end
}// class 끝

이렇게 배열까지 끝이 났다.
배열은 매우매우 중요하면서도 응용할 수 있는 부분이 많아서
문제를 좀 빡세게 넣었다.
다음 시간에도 꿀 떨어지고 중요한 자바(JAVA) 포스팅은 계속된다.

profile
[Java SQL HTML CSS JS Studying] 발전을 꿈꾸며 이상을 실현합니다
post-custom-banner

0개의 댓글