U E D R , A S I H C RSS

한자공/시즌3/20140709 (rev. 1.74)

한자공/시즌3/20140709


1. 일시

  • 오후 12시 15분 ~ 12시 45분

2. 참가자

유재범 불참
최다인 참석
이지수 참석
김용준 불참
김정민 참석

3. 진행 상황

  • 김정민 학우의 발표
    • Java의 정석 - Chapter 5

3.1. 발표 내용

  • C에서의 배열은 선언과 생성이 동시에 되나, Java에서는 선언과 생성이 다름.

int[] arr; : 선언
arr = new int[5]; : 생성
int[] arr = new int[5]; : 선언과 생성, 동시에.
  자동으로 0으로 초기화
int[] arr = {1, 2, 3, 4, 5}; 이런 형식도 가능.
  단, 이 경우에는 선언과 생성을 동시에 할 경우에만.
  먼저 선언을 했을 경우에는 
int[] arr;
arr = new int[]{1, 2, 3, 4, 5};

  • 생성 후 크기 변경도 가능.

int[] arr;
arr = new int[3];
arr = new int[5];
→ 문제없음.
  • 함수의 return형이 배열인 것도 가능.
    • public static int[] function() {...}

  • arr.length : 배열의 길이값을 return하는 메서드

  • 다차원 배열

선언 : int[][] arr;
생성 : arr = new int[3][]; → 열의 길이를 비워둘 수 있음

arr[0] = new int[3];
arr[1] = new int[2]; → 각 행의 배열 길이가 모두 달라도 됨

//다차원 배열에서의 length 메서드
arr.length == 3
arr[0].length == 3
arr[1].length == 2
  • for-each 구문

int[] arr = {1, 2, 3, 4, 5};

for (int e : arr) {
    System.out.print(e);
}
→ 출력값 : 12345

for (int e : arr) {
    e++;
    System.out.print(e);
}
→ 출력값 : 23456

//e는 index가 아니라, arr[index]의 값을 잠깐 받아놓는 역할.
  • arraycopy 메소드

int[] arr1 = {1, 2, 3};
int[] arr2 = {11, 12, 13, 14};
System.arraycopy (arr1, 0, arr2, 1, 2);

→ arr2 = {11, 1, 2, 14};
// arr1[0]부터 2개의 값을, arr2[1]부터 2개의 값으로 복사.
  • main함수의 String[] args ??
    • command line에서 문자열들을 입력받을 수 있음.

java program abc 123

args[0] == abc
args[1] == 123

4. 다음 진행

  • Chapter 6
    • 객체지향 프로그래밍 1
  • 발표 : 최다인

5. 과제

  • 임의의 n*n 행렬을 입력받아 (n+1)*(n+1) 행렬을 생성해, (n+1)번째 행과 열에 각 행과 열의 합을 계산하여 넣고 출력하는 프로그램을 작성하라.
    • 행렬의 크기 n은 입력을 받으면 더 쉽다. 안 받고도 만들어보자.
    • n*m으로도 만들어보자.

예시

input
1 2 3
4 5 6
7 8 9

output
1  2  3  6
4  5  6  15
7  8  9  24
12 15 18 45

5.1. 유재범

package hanjagonghomework;
import java.io.*;
public class Homework0709 {
	public static void main(String []ar) throws IOException{
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		System.out.println("행의 길이는 몇입니까?");
		int array = 0;
		array = Integer.parseInt(in.readLine());
		System.out.println("열의 길이는 몇입니까?");
		int column = 0;
		column = Integer.parseInt(in.readLine());
		int [][] matrix = new int[array+1][column+1];
		for(int a=0; a<array; a++){
			for(int b=0; b<column; b++){
				//matrix[a][b]=3*a+4*b+5*a*b+1;
				System.out.print((a+1) + "행 " + (b+1) + "열에는 무엇을 넣으시겠습니까? = ");
				int input;
				input = Integer.parseInt(in.readLine());
				matrix[a][b] = input;
			}
		}
		int sum=0;
		for(int a=0; a<array; a++){
			for(int b=0; b<column; b++){
				sum += matrix[a][b];
			}
			matrix[a][column]=sum;
			sum=0;
		}
		sum=0;
		for(int a=0; a<column; a++){
			for(int b=0; b<array; b++){
				sum += matrix[b][a];
			}
			matrix[array][a]=sum;
			sum=0;
		}
		for(int a=0; a<array+1; a++){
			for(int b=0; b<column+1; b++){
				System.out.print(matrix[a][b] + " ");
			}
			System.out.println();
		}
	}
}

 * 오류수정 완료.
 * 과제가 알고보니 배열 안의 숫자를 다 입력받아야 해서 기존의 코드 주석처리하고 수정 (~~난독종자 여기있습니다.~~)

5.2. 최다인

5.3. 이지수

사용자로부터 n값을 입력받지 않기 때문에 일차 행렬에 원소를 입력받아 입력받은 원소 개수를 이용해서 일차 행렬을 이차 행렬에 복사하는 형태를 취했습니다.
import java.io.*;
import java.util.Scanner;

public class Jisu {
	public static void main(String[] ar) throws IOException{
		int[] tempArr;		   //사용자값을 입력받을 일차 행렬
		int[][] matrix;        //일차 행렬을 복제할 이차 행렬
		int arrLength=0;
		
		tempArr = inputArray();	//일차 행렬에 사용자로부터 원소를 입력받는다.
		arrLength = tempArr.length;
		matrix = cloneArray(tempArr, arrLength); //일차원의 임시 행렬을 이차 행렬로 복사하여 matrix에 대입한다.
		matrix = sumElementOfArray(matrix);    //이차 행렬의 각 행과 열의 원소 값을 합한다.
		printArray(matrix);	//행렬을 출력한다.
		
	}
	
	public static int[] inputArray(){
		int[] arr = new int[1000];
		int length = arr.length;
		int n=0, i, idxNum=0;
		@SuppressWarnings("resource")
		Scanner in = new Scanner(System.in);
        System.out.println(" 원소를 원하는 만큼 입력해주세요\n 이차 정사각행렬을 만들기 위해 입력받는 원소의 개수는 제곱수만큼만 활용됩니다.\n");
		for(i=0; i<length; i++){
			System.out.print(i+1 + "번째 원소(-1은 종료). : ");
			arr[i] = in.nextInt();
				if(arr[i] == -1 && n != 0){ //입력이 종료됐을 경우 입력받은 수와 가장 가까운 제곱수를 구한다.
					n = (int) Math.sqrt(n);
					idxNum = n*n; 
					break;
					}
				else if(arr[i] == -1 && n == 0){
					System.out.println("입력하신 원소가 없네요. 프로그램을 종료합니다.");
					System.exit(-1);
				}
				n++;	
	        }
        	
        int[] resultArr = new int[idxNum];
        System.arraycopy(arr, 0, resultArr, 0, idxNum);
        return resultArr;
	}
	
	public static int[][] cloneArray(int[] oneDimArr, int arrLength){
		int length = (int) Math.pow(arrLength, 0.5);     //여기서 0.5 대신 1/2를 입력하면 안 된다. 왜지...
		int[][] twoDimArr = new int[length+1][length+1];
		int i, j = 0;
		for(i = 0; i<length; i++){
		System.arraycopy(oneDimArr, j, twoDimArr[i], 0, length);
		j = j + length;
		}
		return twoDimArr;
	}
	
	public static int[][] sumElementOfArray(int [][] arr){
		int n = arr[0].length;
		int i, j;
		for(i=0; i<n-1; i++){
			for(j=0; j<n-1; j++){
				arr[i][n-1] += arr[i][j];
				arr[n-1][j] += arr[i][j];
				arr[n-1][n-1] += arr[i][j];
			}
		}
		return arr;
	}
	
	public static void printArray(int[][] arr){
		System.out.println("\n결과 : ");
		for(int[] row : arr){
			for(int col : row){
				System.out.printf("%5d", col);
			}
			System.out.println();
		}
	}
}
예외처리가 필요없게 만듦 + main 메서드 단순화.

다음은 m*n형태의 행렬 계산입니다.
m과 n을 미리 입력받지 않고 사용자가 입력하는 원소 개수에 의해서 정해지는 형태로 하였습니다.
import java.io.*;
import java.util.Scanner;

public class Jisu{
	public static void main(String[] ar)throws IOException{
		int[][] matrix = new int[1000][1000];
		int i=0, j=0, row=1000, col=1000;
		int count=0;
		boolean bool = true;
		
		@SuppressWarnings("resource")		
		Scanner in = new Scanner(System.in);	//행렬 입력받기. 사용자가 입력하는 원소의 개수를 통해 행과 열을 결정한다.
		System.out.println("\n 행렬의 열의 개수부터 결정합니다. 숫자를 원하는 만큼 입력하세요(-1은 종료).\n");
		while(i<row && bool == true){
			System.out.println(i+1+"행 ");
			for(j=0; j<col; j++){
				System.out.printf("\t%d열 : ", j+1);
				matrix[i][j] = in.nextInt();
				
				if(matrix[i][j] == -1 && count == 0){   //사용자가 처음부터 -1을 입력했을 경우
					System.out.println("\n 입력하신 요소가 없습니다. 프로그램을 종료합니다. ");
					System.exit(-1);
				}
				else if(matrix[i][j] == -1 && col == 1000){   //-1을 첫 번째로 입력받았을 때
					System.out.println("\n 이제 행렬의 행의 개수를 결정합니다.\n "
							+ "숫자 입력 중단시 가장 최근에 입력이 완성된 행까지만 저장이 됩니다(-1은 종료).\n");
					col = count; 
					break;
				}
				else if(matrix[i][j] == -1){   //-1을 두 번째로 입력받았을 때
					System.out.println("\n 입력이 종료되었습니다.");
					row = count/col;
					bool = false; 
					break;
						
				}
				count++;
			}
			i++;
		}
		System.out.printf(" 입력하신 행렬은 %d행 %d열 입니다.\n\n", row, col);
		System.out.println(" input");
		printArray(matrix, row, col);
		matrix = sumElementOfArray(matrix, row, col);
		System.out.println(" output");
		printArray(matrix, row+1, col+1);		
	}
	
	
	public static int[][] sumElementOfArray(int[][] arr, int row, int col){
		int i, n, j;
		
			for(n=0; n<col; n++){	//합산하기 전 전에 입력됐던 -1 등의 값으로 인해 생길 수 있는 계산 오류 처리.
				arr[row][n] = 0;
			}
			
		for(i=0; i<row; i++){
			arr[i][col] = 0;		//마찬가지로 -1에 의한 계산 오류를 처리하는 부분.
			for(j=0; j<col; j++){
				arr[i][col] += arr[i][j];
				arr[row][j] += arr[i][j];
				arr[row][col] += arr[i][j];
			}
		}
		return arr;
	}
	
	public static void printArray(int[][] arr, int row, int col){
		int i, j;
		for(i=0; i<row; i++){
			for(j=0; j<col; j++){
				System.out.printf("%5d", arr[i][j]);
			}
			System.out.println();
		}
		System.out.println();
	}
}
메인을 좀 더럽게 짠 것 같군요. 죄송합니다.

5.4. 김용준

import java.util.Scanner;

public class _20140709 {

	public static void main(String[] args) {
		Scanner scan = new Scanner( System.in );

		System.out.print("input n : ");
		int n = scan.nextInt();
		int [][]map = new int[n+1][n+1];

		for(int r = 0; r < n;r++){
			for(int c = 0; c < n;c++){
				map[r][c] = scan.nextInt();
				map[r][n] += map[r][c];
				map[n][c] += map[r][c];
				map[n][n] += map[r][c];
			}
		}
		System.out.printf("\noutput\n");
		for(int r = 0; r <= n;r++){
			for(int c = 0; c <= n;c++){
				System.out.printf("%3d",map[r][c]);
			}
			System.out.println();
		}
	}
}

5.5. 김정민

6. 후기

  • for-each 구문은 다차원에서도 사용 가능한지 궁금하네요. 그리고 자바에서도 다차원 배열이 C와 같이 일차원 배열과 메모리값이 같은지도 알아보고 싶군요. - 유재범
    • for-each를 활용한 2차 배열 출력입니다. - 이지수

	int[][] array = new int[][]{{1, 2, 3}, {2, 3, 4}};
		for(int[] row : array){
			for(int col : row){
				System.out.print(col);
			}
		}
  • 아까 정민이가 배열을 선언하고 나서 그 크기를 바꾸는 것은 괜찮다고 했는데, 그렇게 할 경우 새로운 크기의 배열은 무조건 0으로 초기화가 되는군요...값 보존이 안 되네요.

   int[] arr = new int[]{1,2,3,4};
   arr = new int[3];
        for(int n: arr){
           System.out.print(n + " ");
          }
이렇게 할 경우
 0 0 0 
이렇게 나와요. - 이지수
  • new라는 것 자체가 메모리를 할당해주는건데, arr에 새로 new int[]를 해주는 순간 기존의 할당된 메모리와 관계없이 다른 메모리가 할당되는 거니까 라고 설명하면 되려나? - 최다인
  • java에서는 주소값을 볼 수 있는 방법이 없나 궁금하네요. 주소값 볼 수 있으면 C언어와 java의 배열 차이점을 구분 할 수 있을탠데요. - 유재범
    • 찾아보니까 가능하다는 말은 없습니다. 일단은 java에서는 주소값을 직접 볼 수 없다고 잠정적으로 결론을 내렸는데 정확한 답을 아시는 분은 답변 해주세요. - 유재범
  • 방금 찾은 건데 java는 call by reference 같다고 생각하겠지만 call by value라고 합니다... 는 저도 잘 모르겠네요. 자세히 찾고 수정하도록 하겠습니다.(일단 질문은 던지고 본다.) - 유재범
    • primitives도 object도 call by value를 한다고 합니다. 정확한 해석인지는 모르겠지만 sun사에서 point라는 표현을 잘못 사용하였다고 된 것으로 봐서 java의 포인터는 우리가 C에서 알던 포인터와 조금 다른 것인 것 같습니다. 자료를 찾은 사이트를 대신 올립니다. http://javadude.com/articles/passbyvalue.htm - 유재범
  • System.out.print(배열이름)하면 볼 수 있답니다. 그러나 이 경우에는 두 배열을 이름으로 구분할 수 없자나요..둘의 주소값이 같은지다른지 어떻게 확인할까요ㅠ - 이지수
    • new 한번 하고 print로 출력 하고 다시 new할당하고 출력. - 최다인
      • 아 그거 해봤었는데 주소값 같게 나오더라구요ㅎㅎ - 이지수
  • 상속이란 개념을 미리 봐서 그런지 주소값이 필요하다는 생각이 안 드네요. - 김용준
  • 잌ㅋㅋ, 저거 안되는군요. 사실 저거 잘 모르고 설명한거라.. 죄송요 - 김정민
  • 지수 과제코드가 왜이리 길음? 부담스럽다. - 김용준
  • 질문을 잘못봤다고 합니다. 결국 설명이 잘못됨.. - 김정민
  • 이게 맞는거 같습니다 - 김용준

int [] a; // 배열의 선언
 a=new int[3]; // 배열의 생성 - int형의 공간을 3개로 만듬.(JVM이 메모리 할당) 


Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:31:31
Processing time 0.0328 sec