Java - 기본기

10. 배열 다루기 활용편 (2) : 총합, 평균, 섞기, 로또 만들기

TerianP 2021. 10. 11.
728x90

이번에는 따로 설명보다는 배열을 활용한 각종 코드에 대해서 공부하였다.

아래에는 해당 코드+설명을 함께 적도록 하겠다.

 

1. 배열 요소들의 총합&평균 구하기

	static void Ex1() {
		int sum = 0;
		float average = 0f;
		
		int[] score = {100, 88, 90, 36, 80};
		
		for(int i=0; i<score.length; i++) {
			sum+=score[i];
		}
		average = sum/(float)score.length; 
		// 계산결과를 float 타입으로 얻기위해서는 score.length 와 sum 둘 중 하나를 float 으로 형변환해야함
		
		System.out.println("sum = "+sum);
		System.out.println("avgerage = "+average);
	}

 

  • - 총합이란 결국 각 요소들의 합을 의미하기 때문에 for 문을 사용하여 각 배열의 요소들을 구해온 후 sum 변수에 담아서 저장하면 된다. 평균도 마찬가지도 sum 을 배열의 길이만큼 나누면 되기 때문에 그대로 계산식을 작성해준다.
  • 이때 중요한 것은 평균은 소수점을 포함하여 float 타입으로 구해야하기 때문에 float 로 형변환 해야한다는 것을 명심한다.

 

2. 배열의 최솟값, 최댓값 구하기

	static void Ex2() {
		
		int[] score = {70, 88, 90, 36, 80};
		int max = score[0]; // 배열의 첫 번째 값으로 최대값을 초기화
		int min = score[0]; // 배열의 첫 번째 값으로 최소값을 초기화
		
		
		for(int i=0; i<score.length; i++) {
			if(score[i]>max) { // score[i] 값이 현재 저장된 max보다 크면 그 값을 max 에 저장
				max = score[i]; 
			}else if(score[i]<min) { // score[i] 값이 현재 저장된 min 보다 작으면 그 값을 min 에 저장 
				min = score[i];
			}
		}
		System.out.println("최대값 : "+max);
		System.out.println("최소값 : "+min);
	}
  • 배열의 최솟값과 최댓값을 구할때 중요한 것은 각 최댓값 최솟값을 구할때 사용할 변수에 0 이 아닌 배열의 첫번째 값을 담아두는 것이다.
  • 나머지는 for 문을 활용하여 각 요소들을 비교하는데 이때 max 에는 큰 값을 저장하고, min 에는 작은 값을 저장한다.

 

3. 배열 요소 섞기

	static void array_3() {
		int[] numArr = {0,1,2,3,4,5,6,7,8,9};
		System.out.println(Arrays.toString(numArr));
		
		for(int i=0; i<100; i++) { // 100번 반복
			int n = (int)(Math.random()*10); // 0 ~ 9 까지 숫자중 임의로 1개 지정
			
			// 여기서부터는 numArr 의 0 번째 값과 n 번째 값을 서로 바꾸는 코드
			// 정렬 코드 짤 때 많이 쓰임
			int tmp = numArr[0]; // tmp 에 numArr[0] 번째 값을 넣음
			numArr[0] = numArr[n]; // numArr[0] 에 numArr[n] 값을 넣음
			numArr[n] = tmp; // numArr[n] 에 tmp 값을 넣음
		}
		System.out.println(Arrays.toString(numArr));
	}
	
	static void array_4() { // 섞는 방법으로는 이게 더 좋음
		int[] numArr = {0,1,2,3,4,5,6,7,8,9};
		System.out.println(Arrays.toString(numArr));
		
		for(int i=0; i<numArr.length; i++) { // 100번 반복
			int n = (int)(Math.random()*10); // 0 ~ 9 까지 숫자중 임의로 1개 지정
			
			// 여기서부터는 numArr 의 i 번째 값과 n 번째 값을 서로 바꾸는 코드
			// 즉 0부터 순서대로 0과 n 번째 값을 교환, 1과 n 번째 값을 교환 ----
			// 최종적으로는 numArr 배열의 길이만큼 각 요소들을 돌아가면서 n 번째 값과 교환
			int tmp = numArr[i]; // tmp 에 numArr[i] 번째 값을 넣음
			numArr[i] = numArr[n]; // numArr[i] 에 numArr[n] 값을 넣음
			numArr[n] = tmp; // numArr[n] 에 tmp 값을 넣음
			

			System.out.println(i+" 번째 회차 = "+Arrays.toString(numArr));
		}
		
		System.out.println(Arrays.toString(numArr));
	}
  • 배열의 요소를 섞을 때는 2가지 방법이 가능하다.
  • 첫 번째는 array_3 메소드처럼 섞는 방법이다. 이 방법은 일정 횟수를 반복하면서 배열의 0 번째 값과 배열의 임의의 값을 바꾸는 것을 반복하는 것이다. 
		for(int i=0; i<100; i++) { // 100번 반복
			int n = (int)(Math.random()*10); // 0 ~ 9 까지 숫자중 임의로 1개 지정
			
			// 여기서부터는 numArr 의 0 번째 값과 n 번째 값을 서로 바꾸는 코드
			// 정렬 코드 짤 때 많이 쓰임
			int tmp = numArr[0]; // tmp 에 numArr[0] 번째 값을 넣음
			numArr[0] = numArr[n]; // numArr[0] 에 numArr[n] 값을 넣음
			numArr[n] = tmp; // numArr[n] 에 tmp 값을 넣음
		}
  • 이 부분만 떼어놓고 보면 훨씬 이해가 쉬운데 n 이라는 변수에 0 ~ 9 까지의 임의의 숫자를 1개 지정한다. 이 숫자는 numArr[n] 으로 사용하여 n 번째 배열의 요소를 불러오는데 사용된다. 이때 해당 배열은 0 번째 값에 0, 1번째 값은 1 로 지정되어 있기 때문에 n의 값이 5인 경우 배열의 5번째 요소값 즉, 5를 가져오게 된다.
  • 다음으로 임시 변수 tmp 에 numArr[0] 번째 값을 저장하고 numArr[0] 번째 값에는 numArr[n] 번째 값을 저장한다. 이후 tmp 에 저장되어있던 numArr[0] 번째 값을 다시 numArr[n]에 넣어준다. 이 코드는 변수의 값을 바꾸는데 자주사용되는 코드로 특히 정렬 코드를 짤 때 자주 사용된다. 이렇게 바꾸는 것을 총 100번 반복한다.

 

  • 두 번째 방법은 첫 번째 방법보다 훨씬 좋은 방법이다. 첫 번째 방법에서는 numArr[0] 번째 값을 지정하고 다른 배열의 값과 바꾸었지만 이번에는 for 문에서의 i 변수를 사용하여 임의의 배열 요소와 바꾸는 방법이다.
		for(int i=0; i<numArr.length; i++) { // 배열의 길이만큼 반복
			int n = (int)(Math.random()*10); // 0 ~ 9 까지 숫자중 임의로 1개 지정
			
			// 여기서부터는 numArr 의 i 번째 값과 n 번째 값을 서로 바꾸는 코드
			// 즉 0부터 순서대로 0과 n 번째 값을 교환, 1과 n 번째 값을 교환 ----
			// 최종적으로는 numArr 배열의 길이만큼 각 요소들을 돌아가면서 n 번째 값과 교환
			int tmp = numArr[i]; // tmp 에 numArr[i] 번째 값을 넣음
			numArr[i] = numArr[n]; // numArr[i] 에 numArr[n] 값을 넣음
			numArr[n] = tmp; // numArr[n] 에 tmp 값을 넣음
			

			System.out.println(i+" 번째 회차 = "+Arrays.toString(numArr));
		}
  • 이때 변수 i 는 배열의 총 길이만큼 반복하며 numArr[i] 번째 값과 임의의 수 n 번째 배열의 값을 바꿔주게 된다. 이렇게 바꾸게 되면 여러번 바꿀 필요없이 배열의 각 요소를 바꿀 수 있게 된다.

 

4. 로또 만들기 (1) 동영상 강의랑 똑같이 만들기

로또 만들기는 2가지 방법으로 만들어 보았다. 첫 번째는 동영상 강의에서 나온 예시와 똑같이 코드를 짜서 만들어보았고, 다음으로는 내가 원하는대로 몇가지 조건을 추가해서 만들어보았다.

먼저 동영상 강의에서 나온 예시를 공부해보자.

	static void lotte() {
		int[] lotte = new int[45];
		int tmp=0; // 두 값을 바꾸는데 사용할 임시 변수
		int j = 0; // 임의의 값을 얻어서 저장할 변수
		
		// 배열의 각 요소에 1~45의 값을 저장
		for(int i=0; i<lotte.length; i++) {
			lotte[i] = i+1; // 0 번째에는 1, 1번째에는 2, ---- 44번째에는 45
		}
		//System.out.println(Arrays.toString(lotte));
		
		for(int i=0; i<6; i++) {
			j = (int)(Math.random()*45);
			tmp = lotte[i]; // tmp에 lotte[0] 번째 값 저장
			lotte[i]=lotte[j]; // lotte[i] 번째 값에 lotte[j] 번째 값 저장
			lotte[j]=tmp; // lotte[j] 번째 값에 tmp 값 저장
			System.out.println(Arrays.toString(lotte));
			
			System.out.println(i+"번째 로또 번호 = "+"["+lotte[i]+"]");
		}
	}

1) 먼저 lotte 라는 배열과 변수 tmp, 변수 j 를 선언한다.

2) 다음으로 lotte 배열의 각 요소에 1 ~ 45 까지의 값을 저장한다. 이때 활용되는 코드는 다음과 같다. 사실 공부하기 전까지는 이렇게 저장하는 방법을 전혀 생각지도 못했다. 이 방법으로 하면 내가 뒤에서 쓸 방법과 비교에서 훨씬 깔끔하게 저장할 수 있는데 그 이유는 바로 '중복' 되는 값이 없기 때문이다.

		// 배열의 각 요소에 1~45의 값을 저장
		for(int i=0; i<lotte.length; i++) {
			lotte[i] = i+1; // 0 번째에는 1, 1번째에는 2, ---- 44번째에는 45, 중복값이 있을 수가 없다
		}

 3) 다음으로 for 문을 통해서 배열의 6번째 값까지만 뽑아낸다(로또 번호는 총 6개니까). 이때 단순히 뽑아내면 1부터 순서대로 뽑아져나오기 때문에 바로 위에서 사용했던 처음 0번째부터 6번째의 값까지 돌아가면서 각각 임의의 변수와 값을 바꾸는 방법을 사용한다.

		for(int i=0; i<6; i++) {
			j = (int)(Math.random()*45); // 0 ~ 45까지 임의의 숫자 생성
			tmp = lotte[i]; // tmp에 lotte[0] 번째 값 저장
			lotte[i]=lotte[j]; // lotte[i] 번째 값에 lotte[j] 번째 값 저장, i가 23인 경우 23번째 값을 lotte[j]에 저장
			lotte[j]=tmp; // lotte[j] 번째 값에 tmp 값 저장
			System.out.println(Arrays.toString(lotte)); // 0 ~ 5번째 값까지 잘 바꾸어졌는지 출력
			
			System.out.println(i+"번째 로또 번호 = "+"["+lotte[i]+"]");
		}

4) 아래의 출력 결과를 확인해보면 0번째 값부터 5번째 값까지만 바뀐 것을 확인 할수 있다.

[33, 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, 1, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45]
########### 0 번째를 32 번째 값과 바꿀거에요 ###########
0 번째 로또 번호 = [33]
[33, 3, 2, 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, 1, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45]
########### 1 번째를 2 번째 값과 바꿀거에요 ###########
1 번째 로또 번호 = [3]
[33, 3, 40, 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, 1, 34, 35, 36, 37, 38, 39, 2, 41, 42, 43, 44, 45]
########### 2 번째를 39 번째 값과 바꿀거에요 ###########
2 번째 로또 번호 = [40]
[33, 3, 40, 35, 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, 1, 34, 4, 36, 37, 38, 39, 2, 41, 42, 43, 44, 45]
########### 3 번째를 34 번째 값과 바꿀거에요 ###########
3 번째 로또 번호 = [35]
[33, 3, 40, 35, 42, 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, 1, 34, 4, 36, 37, 38, 39, 2, 41, 5, 43, 44, 45]
########### 4 번째를 41 번째 값과 바꿀거에요 ###########
4 번째 로또 번호 = [42]
[33, 3, 40, 35, 42, 17, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 6, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 1, 34, 4, 36, 37, 38, 39, 2, 41, 5, 43, 44, 45]
########### 5 번째를 16 번째 값과 바꿀거에요 ###########
5 번째 로또 번호 = [17]

 

5. 나만의 방법으로 로또 구하기!!

나는 로또를 만들기 위해서 다음 조건을 추가했다.

  • 1부터 45까지의 숫자중에서 랜덤으로 값이 뽑아져야한다. 이때 중복되는 숫자가 있어서는 안된다.
  • 두 번째로 뽑아진 숫자가 크기 순서대로 출력되었어야 한다는 것이다.

이렇게 조건을 추가한뒤 지금까지 배운 것들을 활용해서 코드를 작성해보았다.

	static void My_lotte_1() {
		int[] lotte = new int[6];
		int tmp=0;
		int num=0;
		
		Loop1 : 
			for(int i=0; i<lotte.length; i++) {
			lotte[i] = (int)((Math.random()*45)+1);
//			System.out.println(Arrays.toString(lotte));
			
			for(int j=0; j<i; j++) {
				num+=1; // 이 for 문을 몇번 반복했는지 확인해보자, 반복할때마다 +1
				if(lotte[i]==lotte[j]) {
//					System.out.println(Arrays.toString(lotte));
					i--;
					continue Loop1;
				}
			}
		}
		System.out.println("num = "+ num);
		System.out.println(Arrays.toString(lotte));

		// 선택정렬 
		for(int i=0; i<lotte.length; i++) {
			for(int j=i+1; j<lotte.length; j++) {
				if(lotte[i]>lotte[j]) {
					tmp=lotte[i];
					lotte[i]=lotte[j];
					lotte[j]=tmp;
					System.out.println(Arrays.toString(lotte));
				}
			}
		}
		
		System.out.print("최종 로또 번호는 : ");
		for(int k : lotte) { // 향상된 for 문
			System.out.print(k + " ");
		}
	}

1) 먼저 Math.random 함수를 사용해서 1 ~ 45 까지의 숫자중 랜덤하게 6개의 숫자를 뽑아와서 lotte 배열에 저장하였다. 다만 이렇게 바로 저장하면 아주 높은 확률로 중복되는 숫자가 있다. 이를 방지하기 위해서 for 문을 하나 더 넣어서 0 부터 i 번째까지 요소들을 비교하면서 둘이 같은 경우 i 를 하나 줄이고, 다시 6개의 숫자를 뽑는다.

 

2) 만약 i 번째와 j 번째가 중복되는 경우 숫자를 i 를 하나 줄이고 숫자를 뽑는 반복을 계속한다. 최종적으로는 중복이 없는 숫자가 뽑아진다. 예를 들어 i = 3, j=2 일 때 중복된 숫자가 발생한 경우, i --; 를 통해서 i 를 2로 내리고 Loop1 즉 임의의 숫자를 뽑는 for문으로 돌아가 2번째(i =2) 배열값부터 다시 임의의 숫자를 생성하여 넣는다. 이런식으로 숫자의 중복을 막을 수 있다.

		Loop1 : 
			for(int i=0; i<lotte.length; i++) {
			lotte[i] = (int)((Math.random()*45)+1);
			System.out.println(Arrays.toString(lotte));

			
			for(int j=0; j<i; j++) { // j는 0번째부터 시작, i보다 작을때까지만 반복
				if(lotte[i]==lotte[j]) { // i번째와 j 번째가 같은 경우
					i--; // i를 하나 내리고
					continue Loop1; // 숫자 뽑는 것을 반복
				}
			}
		}

3) 다음으로 오름차순으로 정렬하는 방법이다. 아래 코드는 선택 정렬을 할때 사용되는 코드로 선택정렬에 대해서는 추후 알고리즘 부분에서 다루도록 하겠다.

  • 선택정렬은 쉽게 이야기해서 0번째 값과 1 번째 값부터 비교하기 시작해서 0번째 값과 2번째 값, 3번째 값 으로 순서대로 비교하여 정렬하는 방법이라고 생각하면 된다.
		for(int i=0; i<lotte.length; i++) { // 0번째부터 배열의 끝까지 반복
			for(int j=i+1; j<lotte.length; j++) { // i 보다 하나 큰 값부터 배열의 끝까지 반복
				if(lotte[i]>lotte[j]) { // i값이 j 보다 큰 경우 i와 j를 교환
					tmp=lotte[i];
					lotte[i]=lotte[j];
					lotte[j]=tmp;
					System.out.println(Arrays.toString(lotte));
				}
			}
		}

4) 최종적으로 결과는 아래와 같이 나온다. 

num = 15 // 반복 횟수
[38, 11, 43, 39, 44, 28] // 임의의 숫자 생성됨
[11, 38, 43, 39, 44, 28] // 정렬 시작
[11, 28, 43, 39, 44, 38]
[11, 28, 39, 43, 44, 38]
[11, 28, 38, 43, 44, 39]
[11, 28, 38, 39, 44, 43]
[11, 28, 38, 39, 43, 44]
최종 로또 번호는 : 11 28 38 39 43 44 // 정렬 완료
  • 여기서 num 값이 정확히 반복되는 횟수가 나오는지는 솔직히 확실하지 못하다. 이 부분은 나중에 좀 더 공부해서 확실하게 알게되면 더 적어두도록 하겠다.

댓글