[필기정리]Day10 - 2차원배열, 배열 예제문제 등

SW/Java

2020. 6. 24. 00:33

#2차원 배열

- 마찬가지로 객체 형태로 컨트롤 한다

 

ex)

int[ ][ ] arr = new int[2][3];

arr[0][0] = 10;
arr[0][1] = 20;
arr[0][2] = 30;

arr[1][0] = 40;
arr[1][1] = 50;
arr[1][2] = 60;

 

- 2차원 배열 for문 작성방법

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

ex)

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

 

 

- 2차원 배열도 선언과 동시에 초기화 할 수 있다.

 문법적으로 크기를 명시 하면 에러가 발생한다.

int[ ][ ] arr = new int[ ][ ] {  
		{10,20,30}
		{40,50,60}
		{70,80,90}
		};

- 두 가지 방법 모두 가능하지만 아래의 방법으로 하는 것이 더 편리해 선호되는 방법이다.

int[ ][ ] arr = {
		{10,20,30}
		{40,50,60}
		{70,80,90}
		};

 

- 자바에서는 2차원 배열에서 행의 길이가 다른 배열 문법적으로 가능함 (cc++은 안 됨)

int[ ][ ] arr = {              
		{10,20}
		{40,50,60}
		{70,80,90,100}
		};
for(int i=0;i<arr.length;i++) 
{
	for(int j=0;j<arr[i].length;j++)
	{
		System.out.println(arr[i][j]);
	}
}
int[ ][ ] arr2;
arr2=arr;
System.out.println(arr[1][1]);

 

- 주소 저장하기 위해선 배열의 형태가 동일해야 한다.

int[ ]tmp;
tmp=arr[0][0]; (x) //integer 1차원 배열의 주소만 넣을 수 있어 2차원 배열은 불가능
int[ ]tmp;

tmp=arr[0]; // tmp=2000번지의 주소값이 들어감
System.out.println(tmp[0]);

arr[0] = arr[1]; //3000번지의 주소값이 들어감
arr[1] = tmp;
System.out.println(tmp[0][0]); //40 출력

 

Q-1.

다음 메소드는 int1차원 배열에 저장된 값을 두 번째 매개변수로 전달된 값의 크기만큼 전부 증가시킨다.

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

이 메소드를 기반으로(이 메소드를 호출하는 형태로)

int2차원 배열에 저장된 값 전부를 증가시키는 메소드를 다음의 형태로 정의하자.

 

public static void addTwoDArr(int[][] arr, int add) { ... }

, 위 메소드는 2차원 배열의 가로, 세로 길이에 상관없이 동작해야 하며,

위의 메소드가 제대로 동작하는지 확인하기 위한 main 메소드도 함께 정의해야 한다.

 

A.

class Question13_2_1
{
	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[] args)
	{
		int[][] arr = {
			{1, 2, 3},
			{4, 5, 6},
			{7, 8, 9}
		};

		addTwoDArr(arr, 7);
	
		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();
		}

	}
}

 

Q-2.

다음의 형태로 표현된 2차원 배열이 존재한다고 가정해보자.

 

1 2 3

4 5 6

7 8 9

 

이러한 형태를 갖는 int2차원 배열이 인자로 전달되면,

다음의 형태로 배열의 구조를 변경시키는 메소드를 정의해 보자.

 

7 8 9

1 2 3

4 5 6

 

A.

class Question13_2_2
{
	public static void arrShift(int[][] arr)
	{
		int[] lastRow = arr[arr.length-1];
		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 = {
			{1, 2, 3},
			{4, 5, 6},
			{7, 8, 9}
		};
		
	
		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();
		}
		System.out.println();

		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();
		}
	}
}

- cc++에서는 이러한 형태의 작업이 불가능하다.

자바는 주소값을 바꾼 것만으로도 행을 바꾼 것 같은 효과를 볼 수 있다는 장점이 있다.

 

# enhancedFor(향상된 for문, enhaced for statement) ex) for each - 많이 쓰이는 문법

- 구조

for(타입 변수명 : 배열 또는 컬렉션)
{						
	// 반복할 문장
}                        

ex)

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

		int sum=0;
		for(int e : arr)
			sum+=e;
		System.out.println("배열 요소의 합:“+sum);

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

 

- 객체배열 : 배열의 자료형이 참조자료형인 경우

ex)

class Number
{
	public int num;
	public Number(int num)
	{
		this.num=num;
	}	
	public int getNum()
	{
		return num;
	}
}

 

ex)

class EnhancedForInst
{
	public static void main(String[] args)
	{	
		Number[] arr=new Number[]{
			new Number(2),
			new Number(4),
			new Number(8)
		};
		
		for(Number e: arr) //자료형이 Number여야 한다.
			e.num++;
		
		for(Number e: arr)
			System.out.print(e.getNum()+" ");
		
		System.out.println("");
		for(Number e: arr)
		{
			e=new Number(5);
			e.num+=2;
			System.out.print(e.getNum()+" ");
		}
		
		System.out.println("");
		for(Number e: arr)
			System.out.print(e.getNum()+" "); // 결과 : 3 5 9 출력
	}
}

- 값의 참조를 편하게 할 때 enhancedFor문을 자주 사용하게 된다

 

Q. 다음을 for-each문을 활용하는 형태로 변경해 보자.

public static int minValue(int[] arr) { ... } // 최소값 반환

public static int maxValue(int[] arr) { ... } // 최대값 반환

 

A.

import java.util.Scanner;

class Question13_3
{
	public static int minValue(int[] arr)
	{
		int min = arr[0];
		for(int i : arr)
			if(min>i) min = i;
		return min;
	}
	public static int maxValue(int[] arr)
	{
		int max = arr[0];
		for(int i : arr)
			if(max<i) max = 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));
	}
}

- 다양한 방식들

int[ ][ ] arr; //가장 선호하는 방식
int arr[ ][ ];
int[ ] arr[ ]; 

 

ex)

class MainParam
{
	public static void main(String[] args)
	{
		for(String e: args)
			System.out.println(e);
	}
}

- cmd java MainParam AAA BBB CCC DDD 입력 시

args[0] = AAA
args[1] = BBB
args[2] = CCC
args[3] = DDD

 

Q.

전화번호 관리 프로그램 03단계 문제

 

배열을 이용해서, 프로그램 사용자가 입력하는 정보가 최대 100개까지 유지되도록 프로그램을 변경하자.

그리고 다음의 기능을 추가로 삽입하자.

 

@ 저장 이름, 전화번호, 생년월일 정보를 대상으로 저장의 과정을 진행한다.

@ 검색 이름을 기준으로 데이터를 찾아서 해당 데이터의 정보를 출력해준다.

@ 삭제 이름을 기준으로 데이터를 찾아서 삭제의 과정을 진행한다.

 

우리가 저장하는 데이터 중에는 동명이인의 데이터가 존재하지 않는다고 가정하겠다.

그리고 데이터의 삭제는 다음의 형태로 이뤄져야 한다.

 

"배열의 중간에 저장된 데이터를 삭제할 경우에는,

해당 요소의 뒤에 저장된 요소들을 한 칸씩 앞으로 이동시키는 형태로 삭제를 진행한다."

 

다음의 기능을 담당하는 Manager 클래스를(또는 Control 클래스라 불리는) 정의해서 프로그램을 완성하자.

 

@ 데이터의 저장

@ 데이터의 검색

@ 데이터의 삭제

 

전화번호 관리 프로그램 03단계 프로그램의 실행 예시

 

선택하세요...

1. 데이터 입력

2. 데이터 검색

3. 데이터 삭제

4. 모든 데이터 보기

5. 프로그램 종료

선택 : 1

데이터 입력을 시작합니다.

이름 : 홍길동

전화번호 : 222 - 3333

생년월일 : 991225일생

데이터 입력이 완료되었습니다.

 

선택하세요...

1. 데이터 입력

2. 데이터 검색

3. 데이터 삭제

4. 모든 데이터 보기

5. 프로그램 종료

선택 : 2

데이터 검색을 시작합니다.

이름 : 홍길동

 

이름 : 홍길동

전화번호 : 222 - 3333

생년월일 : 991225일생

데이터 검색이 완료되었습니다. // 없으면 데이터가 없습니다 출력할 것

 

선택하세요...

1. 데이터 입력

2. 데이터 검색

3. 데이터 삭제

4. 모든 데이터 보기

5. 프로그램 종료

선택 : 3

데이터 삭제를 시작합니다.

이름 : 홍길동

데이터 삭제가 완료되었습니다.

 

A.

import java.util.Scanner;

class PhoneBookMain
{
	public static void main(String[] args)
	{
		PhoneBook info=null;
		Scanner sc=new Scanner(System.in);
		int menu =0;
		String name=null, phoneNumber=null, birthday=null;
		PhoneBook[] infoArr = new PhoneBook[100];
		int cnt = 0;
		boolean sflag = false;
		int idx = 0;  
		// 자바는 어느 곳이던 변수 선언 가능하지만 맨 위에 파악하기 쉽도록 몰아서 선언하는 것이 좋다

	while(true) {
		System.out.println("선택하세요...");
		System.out.println("1. 데이터 입력");
		System.out.println("2. 데이터 검색");
		System.out.println("3. 데이터 삭제");
		System.out.println("4. 모든 데이터 보기");
		System.out.println("5. 프로그램 종료");
		System.out.println("선택 :");
		menu=sc.nextInt();
		sc.nextLine();
		
		switch(menu)
		{
			case 1 :
				System.out.println("데이터 입력을 시작합니다.");
				System.out.println("이름 :");
				name = sc.nextLine();
				System.out.println("전화번호 :");
				phoneNumber = sc.nextLine();
				System.out.println("생년월일 :");
				birthday = sc.nextLine();
				info = new PhoneBook(name, phoneNumber, birthday);
				infoArr[cnt++] = info;
				System.out.println("데이터 입력이 완료되었습니다.");
				break;
			case 2 :
				System.out.println("데이터 검색을 시작합니다.");
				System.out.println("검색하시고자 하는 이름을 입력하세요.");	
				name = sc.nextLine();
				for(int i=0;i<cnt;i++)
				{
					if(name.compareTo(infoArr[i].getName()) == 0)
					{
							infoArr[i].showPhoneBook();
							sflag = true;				
					}
	            }        	
				if(!sflag) System.out.println("검색 결과가 없습니다.");
				sflag = false;
				break; // 동명이인이 없기 때문
			case 3 :
				System.out.println("삭제하시고자 하는 이름을 입력하세요.");
				name = sc.nextLine();
				for(int i=0;i<cnt;i++)
				{
					if(name.compareTo(infoArr[i].getName()) == 0)
					{
						idx = i;
						sflag = true;						
						break;
					}
				}
				if(!sflag) System.out.println("삭제하시고자 하는 사람이 없습니다.");
				else
				{
					for(int i = idx; i<cnt-1;i++)
						infoArr[i] = infoArr[i+1];
					infoArr[cnt-1] = null;
					cnt--;
					sflag = false;
					System.out.println("삭제가 완료되었습니다.");
				}				
				break;
			case 4 :
				for(int i=0;i<cnt;i++)
					infoArr[i].showPhoneBook(); 
					//입력된 객체가 없는 경우 null pointer exception 발생
				break;
			case 5 :
				System.out.println("프로그램을 종료합니다.");
				return;
			default : 
				System.out.println("잘못 선택 하셨습니다.");
			}
		}
	}
}
Class PhoneBook
{
	private String name;
	private String phoneNumber;
	private String birthday;

	public PhoneBook(String name, String phoneNumber, String birthday)
	{
		this.name=name;
		this.phoneNumber=phoneNumber;
		this.birthday=birthday;
	}
    public PhoneBook(String name, String phoneNumber) 
    {
		this.name = name;
		this.phoneNumber = phoneNumber;
	}
	public void showPhoneBook()
	{
		System.out.println("이름 : "+name);
		System.out.println("전화번호 : "+phoneNumber);
		System.out.println("생년월일 : "+birthday);
	}
	public String getName()
	{
		return name;
    }    	
}

- manager클래스(control클래스)로 저장해주어 Main클래스를 한 눈에 알아볼 수 있도록 정리해주는 것이 필요하다.

  (Day11에서 자세히 다룰 예정)

 

//Tip - null pointer exception : Null값 때문에 발생하는 Runtime Exception입니다.

 

 

 

728x90