U E D R , A S I H C RSS

한자공/시즌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 메서드 단순화.
+pow메서드 사용시 0.5는 되고 1/2는 안 되는 문제 해결. 1/2가 0으로 계산되는 것이었다.


다음은 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();
	}
}
메인을 좀 더럽게 짠 것 같군요. 죄송합니다.

조영준선배의 도움으로 과제 예제에 나온 그대로 출력되도록 하였습니다.ㅎㅎ
import java.io.*;
import java.util.Scanner;

public class Jisu{
	public static void main(String[] ar)throws IOException{
		@SuppressWarnings("resource")
		java.util.Scanner scanner = new java.util.Scanner(System.in);
		int[][] tempArr = new int[1000][1000];
		int i=0, j=0, count, n=2;

		String input;
		String[] inputArray;
			
		System.out.println(" input");
			for(i=0; i<n; i++){
				input = scanner.nextLine();
				inputArray = input.split(" ");
				count=0;
				for(String s : inputArray){
					tempArr[i][count] = Integer.valueOf(s);
					count++;
				}
				n = count;
			}
						
			for(i=0; i<n; i++){
				for(j=0; j<n; j++){
					tempArr[i][n] += tempArr[i][j];
					tempArr[n][j] += tempArr[i][j];
					tempArr[n][n] += tempArr[i][j];
				}
			}
			System.out.println(" output");
			for(i=0; i<n+1; i++){
				for(j=0; j<n+1; j++){
					System.out.printf("%5d", tempArr[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();
		}
	}
}
  • n 없이 Input

import java.util.Scanner;

public class _20140709 {

	public static void main(String[] args) {
		Scanner scan = new Scanner( System.in );
		System.out.println("input(0을 입력하면 완료)");
		int []tmp = new int[100];
		int i;
		
		for(i = 0; true; i++){
			tmp[i] = scan.nextInt();
			if(tmp[i] == 0) break; 
		}
		
		i = (int)Math.sqrt(i);
		int [][]map = new int[i+1][i+1];
		
		for(int r = 0; r < i;r++){
			for(int c = 0; c < i;c++){
				map[r][c] = tmp[c+r*3];
				map[r][i] += map[r][c];
				map[i][c] += map[r][c];
				map[i][i] += map[r][c];
			}
		}
		System.out.printf("\noutput\n");
		for(int r = 0; r <= i;r++){
			for(int c = 0; c <= i;c++){
				System.out.printf("%3d",map[r][c]);
			}
			System.out.println();
		}
	}
}
  • n 입력 없고 완료시 엔터 한번만 더치면 되는 NxM 행렬

import java.util.Scanner;
import java.io.*;

public class NxM {
	public static void main(String[] args) {
		Scanner scan = new Scanner( System.in );
		int N,M=0;
		String tmpStr;
		String []tmpArr;
		int [][]map = new int[1000][1000];
		
		System.out.println("input(엔터 두번시 완료)");
		for(N = 0; true; N++){
			tmpStr = scan.nextLine();
			tmpArr = tmpStr.split(" ");
			
			try{
				for(int jud = 0; jud < tmpArr.length; jud++)
					map[N][jud] = Integer.valueOf(tmpArr[jud]);
			}catch(IllegalArgumentException x){
				for(int r = 0; r < N;r++){
					for(int c = 0; c < M;c++){
						map[r][M] += map[r][c];
						map[N][c] += map[r][c];
						map[N][M] += map[r][c];
					}
				}
			break;
			}// 예외처리를 통한 탈출
			
			if(N == 0) M = tmpArr.length;// NxM에서 M을 구함;
		}
		
		System.out.println("output");
		for(int r = 0; r <= N;r++){
			for(int c = 0; c <= M;c++){
				System.out.printf("%3d",map[r][c]);
			}
			System.out.println();
		}
	}
}

5.5. 김정민

package study;

import java.io.IOException;
import java.util.*;
//자바는 초기화를 좋아하는거같다.
public class study1 {
	public static int input_n() throws IOException
	{
		System.out.printf("n : ");
		@SuppressWarnings("resource")
		Scanner scan = new Scanner(System.in);
		int n = scan.nextInt();
		return n;
	}
	public static void input_matrix(int[][] matrix, int n)
	{
		Scanner scan = new Scanner(System.in);
		for(int i = 0; i<n;i++){
			for(int j =0;j<n;j++){
				matrix[i][j] = scan.nextInt();
			}
			System.out.println("");
		}
	}
	public static void make_matrix(int[][] matrix)
	{
		int length = matrix.length + 1;
		int[][] new_matrix = new int[length][length];
		for(int i=0;i<matrix.length;i++)
			System.arraycopy(matrix[i], 0, new_matrix[i], 0, matrix.length);
		for(int i=0;i<matrix.length;i++){
			for(int j=0;j<matrix.length;j++){
				new_matrix[i][j] += new_matrix[i][matrix.length];
				new_matrix[i][j] += new_matrix[matrix.length][j];
			}
			new_matrix[matrix.length][matrix.length] += new_matrix[i][matrix.length];
		} 
		for(int[] e : new_matrix){
			for(int f : e){
				System.out.printf("%d\t",f);
			}
			System.out.println("");
		}
	}
	public static void main(String[] args) throws IOException
	{
		int[][] matrix = null;
		int n = input_n();
		input_matrix(matrix, n);
		make_matrix(matrix);
	}
}
  • 이거 오류뜸

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.0263 sec