부트캠프(Java)

자바/스프링 개발 부트캠프 4일차 (배열)

동곤일상 2025. 2. 5. 17:56
반응형

5장 배열.pdf
0.35MB

 

 

오늘은 배열 부터 시작

 


 

package chap05;

public class ArrayEx01 {
	public static void main(String[] args) {
		
		int arr[];
		arr = new int[5];
		/*
		 * new 예약어 -->
		 * 1.객체생성( 정수 5개를 저장할 수 있는 객체생성)
		 * 2.기본값 초기화 
		 * 숫자 : 0 , boolean : false , 그외 : null
		 */
		
		//배열의인덱스 0번부터 시작
		arr[0] = 10;
		arr[1] = 20;
		//arr.length = 5 배열의크기
		for (int i = 0; i < arr.length; i++) {
			System.out.println("arr["+i+"] : "+arr[i]);
		}
		System.out.println();
		int []arr2 = new int[]{100,200};
		for (int i = 0; i < arr2.length; i++) {
			System.out.println("arr2["+i+"] : "+arr2[i]);
		}System.out.println();
		
		arr2= arr;
		arr2[3] = 999;
		
		for (int i = 0; i < arr2.length; i++) {
			System.out.println("arr2["+i+"] : "+arr2[i]);
		}System.out.println();
		
		for (int i = 0; i < arr.length; i++) {
			System.out.println("arr["+i+"] : "+arr[i]);
		}
		
		//향상된for문
		System.out.println("향상된for문사용");
		for (int i : arr2) {
			
			System.out.println(i);
		}
	}
}

arr[0] : 10
arr[1] : 20
arr[2] : 0
arr[3] : 0
arr[4] : 0

arr2[0] : 100
arr2[1] : 200


arr2[0] : 10
arr2[1] : 20
arr2[2] : 0
arr2[3] : 999
arr2[4] : 0

arr[0] : 10
arr[1] : 20
arr[2] : 0
arr[3] : 999
arr[4] : 0

향상된for문사용
10
20
0
999
0

arr2 = arr;
로 인해 arr이 참조학있는 객체의 주소값을
arr2에 복사해버렸다
즉  원래 arr2가 참조하고있던 객체는 아무도참조하지않아
GC로인해 사라짐
 
arr과 arr2 는 참조하는 객체가 같아졌으므로
출력결과도 같아지고
 
arr2[3] = 999 로 설정했지만arr[3] 도 999가 되는 것.
 


배열을 이용한 예제

package chap05.exam;

import java.util.Scanner;

/*
 * 정수값 5개 입력받아
 * 입력받은 수의 합계 평균 최대값 ,최소값 , 최대인덱스값 , 최소인덱스값
 */
public class Exam01 {
	public static void main(String[] args) {
		
		Scanner scan = new Scanner(System.in);
		int [] arr = new int[5];
		int sum=0;
		
		
		
		for (int i = 0; i < 5; i++) {
			System.out.print("정수 입력하세요  : ");
			int var = scan.nextInt();
			arr[i] = var;
		}
		
		for (int i : arr) {
			sum+=i;
		}
		System.out.println("합계 : "+sum);
		System.out.println("평균 : "+(double)sum/arr.length);
		
		int min = 0,max=0;
		
		for (int i = 0; i < arr.length; i++) {
			if(arr[min]>arr[i]) {
				min=i;
			}
			if(arr[max]< arr[i]) {
				max = i;
			}
		}
		System.out.println("min : "+arr[min]);
		System.out.println("max : "+arr[max]);
		System.out.println("최대값인덱스 : "+max);
		System.out.println("최소값인덱스 : "+min);
	}
}


정수 입력하세요  : 5
정수 입력하세요  : 7
정수 입력하세요  : 9
정수 입력하세요  : 12
정수 입력하세요  : 45
합계 : 78
평균 : 15.6
min : 5
max : 45
최대값인덱스 : 4
최소값인덱스 : 0

로또번호 예제

(배열알고리즘)
 

package chap05;

import java.util.Arrays;

/*
 * 로또번호생성
 * 1~45 까지의 값을 저장하는 배열생성
 * 배열을 섞는다  , 정렬(sort)
 */
public class ArrayEx03 {
	public static void main(String[] args) {
		
		int[] balls = new int[45];
		int[] lotto = new int[6];
		
		
		for (int i = 0; i < 45; i++) {
			balls[i] = (i+1);
		}
		System.out.println(Arrays.toString(balls));
		
		for (int i = 0; i < 1000; i++) {
			int f = (int)(Math.random() * 45 );
			int t = (int)(Math.random() * 45 );
			//swap 알고리즘 양 값 바꾸기
			int temp = balls[f];
			balls[f] = balls[t];
			balls[t] = temp; 
			//하나의 변수를 두어 중간에서 섞는역할
			//랜덤한 인덱스 값 추출후 섞기
		}
		System.out.println(Arrays.toString(balls));
		
		//lotto 번호선택 0~5 번 인덱스까지
		for (int i = 0; i < lotto.length; i++) {
			lotto[i] = balls[i];
		}
		System.out.println("** 로또 **");
		System.out.println(Arrays.toString(lotto));
		//정렬(sort)
	
		for (int i = 0; i < lotto.length; i++) {
			boolean sortable = true;
			for (int j = 0; j < lotto.length-1-i; j++) {
				/*lotto.length-1-i 로설정한 이유
				 * 일단 j+1 과비교하기떄문에 length가6이라고치면
				 * 4번인덱스 까지만 루프를 돌면5번까지도 비교가 됨
				 * 
				 * 첫번쨰루프에서 0번부터 맨뒤에까지 비교를했으니
				 * (length-1-i)번 인덱스 까지만 비교해주면 된다 
				 */
			
				if(lotto[j]> lotto[j+1]) {
					int temp = lotto[j];
					lotto[j] = lotto[j+1];
					lotto[j+1] = temp;
					sortable = false;
				}
			}
			System.out.print(i+":");
			for (int j : lotto) {
				System.out.print(j+" , ");
			}System.out.println();
			if(sortable)break;
			
		}
		System.out.print("최종정렬 : ");
		for (int i : lotto) {
			System.out.print(i+" , "
					+ "");
		}
	}
}




[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45]
[26, 28, 15, 6, 19, 42, 16, 9, 4, 3, 43, 34, 22, 25, 21, 38, 10, 39, 32, 8, 20, 31, 29, 5, 23, 11, 30, 35, 41, 40, 14, 13, 18, 36, 2, 1, 37, 24, 33, 44, 17, 12, 27, 45, 7]
** 로또 **
[26, 28, 15, 6, 19, 42]
0:26 , 15 , 6 , 19 , 28 , 42 , 
1:15 , 6 , 19 , 26 , 28 , 42 , 
2:6 , 15 , 19 , 26 , 28 , 42 , 
3:6 , 15 , 19 , 26 , 28 , 42 , 
최종정렬 : 6 , 15 , 19 , 26 , 28 , 42 ,

 


10진수 --> 2진수 변환예제

package chap05;

import java.util.Scanner;

/*
 * 10진수입력받아 2진수로변경
 */
public class ArrayEx04 {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		
		System.out.print("정수를 입력하세요 ");
		int num = scan.nextInt();
		int divNum=num; //입력받은 num을 담아놓음
		
		int [] two = new int[32];
		int index = 0; 
		//인덱스는 0번부터시작하므로 값을 저장하기위한 인덱스번호
		
		while(divNum>0) {
			two[index++] = divNum % 2;
			//연산 후에 index값이 하나올라감
			divNum /= 2;
		}
		
		System.out.print(num+"의 2진수 : ");
		for (int i = index-1; i >=0; i--) {
			System.out.print(two[i]);
		}
		System.out.println();
	}
}

정수를 입력하세요 56
56의 2진수 : 111000

 

/////간단한 방법도있음

System.out.println(Integer.toBinaryString(num)); //진법변환

 
 
다른 진법으로 변환하려면 
two[index++] = divNum % 2;
//연산 후에 index값이 하나올라감
divNum /= 2;
이부분만 바꿔주면 된다.
 
예를 들어 10진수를 8진수로 변경하고싶다면 8로 바꿔주면 된다.


 

소문자 갯수 새는 알고리즘( 배열이용 ) 

toCharArray() 이용

 

package chap05.exam;

import java.util.Arrays;

/*
 * str문자열에 저장된 소문자의 갯수 출력
 */
public class Exam3_good {
	public static void main(String[] args) {
		String str = "public static void main(String[] args)";

		String abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toLowerCase();
		char[] abcChar = abc.toCharArray();
		//알파벳을 모두입력 후 toCharArray로 char형배열로변경해줬다

		int[] count = new int[26];
		int[] count2 = new int[26];
		char[] charArray = str.toCharArray();

		//97~122
		for (int i = 0; i < charArray.length; i++) {
			char ch = charArray[i];
			if(ch>='a' && ch <= 'z') {
				count[ch-'a']++;
				//ch가 b 라면 count[1] 에 저장될것
			}}

		//배열을 사용하지않고 하는법
		for (int i = 0; i < str.length(); i++) {
			char ch = str.charAt(i);
			if(ch>='a' && ch <= 'z') {
				count2[ch-'a']++;}

		}

		System.out.println(Arrays.toString(abcChar));
		System.out.println(Arrays.toString(count));
		System.out.println(Arrays.toString(count2));
		for(int i=0;i< count.length;i++) //0~12번까지만 루프
		{
			System.out.print((char)(i+'a') + ":" + count[i]+"-->");
			for (int j = 0; j < count[i]; j++) {
				System.out.print(" *");
				
			}System.out.println();
		}

	}
}

[a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z]
[3, 1, 2, 1, 0, 0, 2, 0, 5, 0, 0, 1, 1, 2, 1, 1, 0, 2, 2, 3, 1, 1, 0, 0, 0, 0]
[3, 1, 2, 1, 0, 0, 2, 0, 5, 0, 0, 1, 1, 2, 1, 1, 0, 2, 2, 3, 1, 1, 0, 0, 0, 0]
a:3--> * * *
b:1--> *
c:2--> * *
d:1--> *
e:0-->
f:0-->
g:2--> * *
h:0-->
i:5--> * * * * *
j:0-->
k:0-->
l:1--> *
m:1--> *
n:2--> * *
o:1--> *
p:1--> *
q:0-->
r:2--> * *
s:2--> * *
t:3--> * * *
u:1--> *
v:1--> *
w:0-->
x:0-->
y:0-->
z:0-->

 


나만의 방법으로 해본것

(아스키코드활용)

 

package chap05.exam;

import java.util.Arrays;

/*
 * str문자열에 저장된 소문자의 갯수 출력
 */
public class Exam03 {
	public static void main(String[] args) {
		String str = "HelloWorldHAha";
		
		String abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toLowerCase();
		char[] abcChar = abc.toCharArray();
		//알파벳을 모두입력 후 toCharArray로 char형배열로변경해줬다
				
		int[] count = new int[26];
		char[] charArray = str.toCharArray();
		int a = 'a';
		int b = 'z';
		//97~122
		for (int i = 0; i < charArray.length; i++) {
			int c = (int)charArray[i];
			if (97<= c && c<=122) {
				count[c%97]++; 
			}
		}
		
		System.out.println(Arrays.toString(abcChar));
		System.out.println(Arrays.toString(count));
		for(int i=0;i< count.length/2;i++)
			{System.out.print((char)(i+'a') + ":" + count[i]+" ");}
		System.out.println();
		//ch[0]이 a이다 그러므로 (char)(97) 을 한다고생각하자
		
		for(int i=count.length/2; i< count.length;i++)
		{System.out.print((char)(i+'a') + ":" + count[i]+" ");}
	}
}

[a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z]
[1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 3, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
a:1 b:0 c:0 d:1 e:1 f:0 g:0 h:1 i:0 j:0 k:0 l:3 m:0 
n:0 o:2 p:0 q:0 r:1 s:0 t:0 u:0 v:0 w:0 x:0 y:0 z:0

 


 

커맨드라인 입력

/*
* 1.소스코딩 : A.java
* 2.컴파일러 : A.class(바이트코드) 생성
* (생성법) javac A.java
* 3.실행 : 인터프리터
* -java A 홍길동 김삿갓 == command라인
* -JVM 환경생성 ,
* -jvm의 (클래스영역)메서드영역에 a.class 라는 바이트코드 road
* -main함수 호출 .String[] args = command라인에서 입력한 문자열을 배열로 전달
* args 배열 값을 사용할 수 있음.
*
*/

public static void main(String[] args) {

 

if(args.length ==0) { //처음 실행 시 argument에는 아무것도없으므로 if문 true

System.out.println("command라인에 파라미터 입력 : ");

return;

}

for (String a : args) {

System.out.println(a);

}

}

동작
args를 힙영역에 올림
힙영역(args) 에 main함수가 실행되며 객체생성
 main함수는 args참조
 
args.length==0 --> 아직 전달된게 아무것도 없을 때
 

(command라인에서 배열객체 받는법)실행법 : 
 
파일 실행 후
우클릭 --> run -> Run configuration 클릭 후
argument 버튼 클릭 후 program Argument의 칸에  문자 입력
 


활용

package chap05.exam;

import java.util.Arrays;

/*
 * command라인에서 숫자입력받아 숫자의 자릿수합 출력
 * 
 * 
 */
public class Exam4 {
	public static void main(String[] args) {
		if(args.length==0) {
        //첫 실행시 args에는 아무런 문자가 있지않으므로 true
			System.out.println("command 숫자 입력 : ");
			return;
		}
		int sum=0;
		
		String string = args[0];
		System.out.println(string);
	;
		int length = args.length;
		System.out.println("length : "+length);
		
		for (int i = 0; i < args.length; i++) {
				String a = args[i];
				for (int j = 0; j < a.length(); j++) {
					char charAt = args[i].charAt(j);
					if('0'<= charAt && charAt<= '9') {
						sum+= charAt - '0';
					}
					
				}
				System.out.println(args[i]+"의 자릿수합 : "+sum);	
		}
	}
}

45678
length : 1
45678의 자릿수합 : 30

 
 arg는 String배열이다
즉 0번 인덱스에만 문자가존재함
1,2,3,4 를 argument에 입력했다면
String[] args = {"1" ," 2", "3","4"} 가 아니다.
String[] args = {"1,2,3,4"} 로 arg.length는 1이다.

1,2,3,4

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1

at chap05.exam.Exam4.main(Exam4.java:20)

 
 


 

test_Array.zip
0.01MB

 
 
오늘의 예제는 이 파일이다
풀면서 내가 어려웟던것을 리뷰해보도록 할게요
 
다음글에서 수정할 가능성도 있음!!!(코딩에 정답은 없는거다)
 


chap05.hard_ex.Test01
 
 *  농장에 강아지,병아리가 있음.
 *  강아지 병아리 전체 마리수 입력받고
 *  강아지 다리수와 병아리 다리수 전체를 입력받는다.
 *  [결과]
 *  강아지 병아리 마리수를 입력하세요
 *  10
 *  강아지 병아리 전체 다리수를 입력하세요
 *  20
 *  강아지 : 8마리
 *  병아리 : 2마리
 *  
 *  [결과]
 *  강아지 병아리 마리수를 입력하세요
 *  10
 *  강아지 병아리 전체 다리수를 입력하세요
 *  10
 *   
 *  계산안됨 

package chap05.hard_ex;

import java.util.Scanner;


public class Test01 {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		boolean check=false;
		
		System.out.print("강아지병아리 마릿수 입력 : ");
		int count= scan.nextInt();
		
		System.out.println("전체 다리 수");
		int leg = scan.nextInt();
		
		int i ,j;
		
		for (i = 0; i <= leg; i++) {
			for ( j = 0; j <= leg; j++) {
				if (i+j==count && i*2 +j*4== leg) {
					System.out.println("병아리 "+i+"마리 "+"강아지 "+j+"마리");
					check = true;
					break;
					
				}
				
			}
		}
		if(check!= true) {
			System.out.println("계산안됨");
		}
	}
}

강아지병아리 마릿수 입력 : 20

전체 다리 수

70

병아리 5마리 강아지 15마리

 
 
생각이 많아지는 문제였다
 
동물 마리 수 입력으로받고(count)
다릿수도 입력으로받고(leg)
 
int i, j 를 변수로 초기화해놓고
 
i 를 leg만큼 for문을 돌리고
중첩 for문으로 j도 leg만큼 돌린다.
 
그 후 조건문으로 i(병아리)+j(강아지)== count(동물 마릿수)  and i*2(다릿수) + j*4(다릿수) == leg
의 조건문을 만들어
병아리 i마리 강아지 j마리라는 출력이 나오게 설계
 
 


chap05.hard_ex.Test06

 
이 문제를 보면서 루프(a) 공백(b) 숫자(c) 등의 생각은 내가 직접 한거다
문제에 나와있진 않음을 주의
 
h(높이)가 4일때를 생각해보니까 숫자가 16개였다
어?? 이거 높이의 제곱만큼의 숫자가 나온다 라는걸 
단번에 알 수 있었다
 
h == 4 
             16
         13 14 15 
     8  9   10  11  12
1  2   3    4    5   6   7 
 

package chap05.hard_ex;

import java.util.Scanner;

public class Test06 {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		System.out.print("입력 :");
		int h= scan.nextInt();
		int sqrt = h*h;
		
		for (int a = 1; a <= h; a++) {
			for (int b = 0; b < (h-a); b++) {
				System.out.print("   ");
					
			}
			for (int c = 0; c < (a*2)-1; c++) {
				
				System.out.printf("%3d",sqrt);
				sqrt--;
			}System.out.println();
			
		}
		
		

	}
}

제곱의 수만큼 숫자가 나온다는 것을 알고
int sqrt 변수에 h(입력받은 높이) 의 제곱을  넣고
 
1번루프(a)는 1부터 h까지 돈다
그 밑에 중첩for문을 이용해
앞 공백의for문(b)을 만든다 공백은(h-a) 번 출력되는 걸 알아냈음( a 가 1일 떄 h-1 번 공백)
 
그 다음 공백for문이 끝나면  (a*2)-1 번의 숫자를 출력해주는 for문(c) 실행. 
숫자는 sqrt의 내림차순으로 실행된다. 
sqrt 출력 후 
sqrt-- 로 하나 낮춰줌
 
맨위의 for문(a)가 끝날때마다 \n 을 해줘서 피라미드형식을 만들고
 

가장 어려웠던  숫자 자리맞춤의 방식은

1 과 10 은 애초에 숫자 크기가 다르다

모든문자의 크기를 3칸(printf("%3d")) 로  설정하고

공백 마저도 3칸으로 해준다면 3자릿수 까지는

일정한 간격을 유지할 수 있게된다

 
 
 


가장어려웟던 문제

 

 
이 문제다
이문제는 나만의 방식으로 풀어봤다
 
5의 경우만 보지말고
7의경우도 한번 생각해봐서 알고리즘을 만들어야 할 것 같았다.

무슨 말을 하는지 모를 수도있다.
 
쉽게 5로 예를 들면
 
총 6번 실행되어야한다.
5 -> 3 -> 1 -> 3 ->5
의 별수가나와야한다.
 

이렇게 돼야 함.
공백 수와 별 수의 법칙은 이런식으로 되는것 같아 적어놓았다 (2개의 step으로 나누어서설명하겠음)


Step 1

 
홀수만 입력가능하므로 h/2 를 하면 중간보다 하나 아래의 숫자가 나오게될거다 5의경우 2가나온다
즉 5 , 4 , 3 의 단계까지만 실행하는 루프를 만든다
 
 b는  c를 위해 써야하므로 for문에서만쓰이지않는 전역변수로 지정해줌.

int b=0;
for (int a = h; a > (h/2); a--) {
				
				for (b = 0; b <h-a ; b++) {
					System.out.print("   ");
				}
				for (int c = 0; c < a-b; c++) {
					System.out.print(" * ");
				}System.out.println();

 
이렇게됐을 때

이러한 결과가 나오게된다 
간격 맞추는 법은 공백의 수와 문자의 크기를 맞추면 된다
(숫자의크기를 넉넉히 잡자)
 
 


Step2
 
내림차순으로 찍히는 별은 다 찍었고
다시 3 과 5를 찍어야한다
h= 5의 경우  h/2 가 2 이다.
4단계로가야 별 3개까찍히고 5단계로 가야 별5개가찍힌다
그걸 응용해서 (h/2)+2 부터 h와 같아질 때 까지 단계루프(k)를 돌려본다. 
여기선 (4 , 5)단계
 
별찍기와 공백의 알고리즘은 같다
( 단계만 k로 바꿔주면 됨 )   
 
주의 =
int j(공백루프변수) 를 전역변수로초기화하지않으면
y(별찍기변수) 에서 j 를 사용할 수 없음

int j=0;
			for (int k = (h/2)+2; k <= h; k++) {
				for (j = 0; j <h-k ; j++) {
					System.out.print("   ");
				}
				for (int y = 0; y < k-j; y++) {
					System.out.print(" * ");
				}System.out.println();
				
			}

 

별의 갯수 3 5 가 정상적으로 출력되는 것을 확인했다
이제 이것을 이어서 출력해보자
 


최종

package chap05.hard_ex;

import java.util.Scanner;

/*
삼각형의 높이를 홀수로 입력하세요
7(h)


                루프(a)      공백(b)          수(별)(c)
*******          7       0(h-a)        7(a-b)
 *****           6        1             5 
  ***            5        2             3
   *             4        3             1      
                
                int a = h; a > (h/2) ; a--  여기서는 내림차순의별이  4번실행 { 7 6 5 4 } 
                
   
 이어서 새로운 루프(K) (h/2)+2 번 부터 실행 여기서는 5번이라고 생각하면 됨
 			그래야 다시 역순으로 올라가는 모양이 나오기 때문 
 			6번(5)-> 5번(3) ->4번(1) -> ((h/2)+2)5번(3) -> ((h/2)+3)6번(5)
 
                루프(k)    공백(j)            별(y)            	
  ***            5        2 (h-k)            3 (k-j)
 *****           6        1                  5
*******          7        0                  7
 
 */
public class Test08 {
	public static void main(String[] args) {
		
		Scanner scan = new Scanner(System.in);
		System.out.print("높이를홀수로 입력 : ");
		int h = scan.nextInt();
		
		int b= 0;
		if(h%2==0) {
			System.out.println("홀수만됩니다");
		}
		else {
			for (int a = h; a > (h/2); a--) {
				
				for (b = 0; b <h-a ; b++) {
					System.out.print("   ");
				}
				for (int c = 0; c < a-b; c++) {
					System.out.print(" * ");
				}System.out.println();
				
			}
			int j=0;
			for (int k = (h/2)+2; k <= h; k++) {
				for (j = 0; j <h-k ; j++) {
					System.out.print("   ");
				}
				for (int y = 0; y < k-j; y++) {
					System.out.print(" * ");
				}System.out.println();
				
			}
		}
	}
}

 
숫자(홀수)를 올려도 모래시계 모양이
유지되는것을 확인!!!!
 
 
https://github.com/donggonyoo/javaStudyGudee/tree/main/chap05/src/chap05/hard_ex

 

javaStudyGudee/chap05/src/chap05/hard_ex at main · donggonyoo/javaStudyGudee

Contribute to donggonyoo/javaStudyGudee development by creating an account on GitHub.

github.com

내가 푼 파일들은 여기 있다
 
폴더:

hard_ex.zip
0.01MB