Java - 알고리즘

백준 JAVA - 4단계 1차원 배열 활용하기(1)

TerianP 2021. 10. 15.
728x90

이번에는 1차원 배열 문제를 풀어보았다. 뭔가 이전에 for 에 비해서 난이도가 확! 올라간 것 같은 느낌이였다.

while 문을 그냥 넘긴 이유는 for 문을 한 번 했으니까 다른 문제를 먼저 접해보고 싶었다.

 

1차원 배열 문제중 10818번, 2562번, 2577번을 풀이 및 코드이다.

 

1. 10818번 - 최솟값, 최댓값 찾기

	static void Q_10818() throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

		// 변수 초기화
		int num1 = 0;
		int min= 0;
		int max = 0;

		num1 = Integer.parseInt(br.readLine()); // 정수 N을 입력받음

		int[] array = new int[num1]; // N 개의 정수를 갖는 배열 array 생성

		String num2 = br.readLine(); // 정수 N개를 입력받음
		String[] tmp = num2.split(" "); // 입력받은 정수를 split 로 나눠서 배열로 생성

		if(1<=num1 && num1<=1000000) { // num1 은 1 이상 100000 이하
			if(tmp.length==num1) { // 두번째로 입력받은 정수의 갯수가 N개여야 함
				for(int i=0; i<array.length; i++) {
					array[i] = Integer.parseInt(tmp[i]);
				}
				max = array[0]; // max 값과 min 값 초기화
				min = array[0]; // 배열의 맨 첫번째 값으로 초기화

				for(int j=0; j<array.length; j++) {
					if(array[j]>max) { // 최대값 구하기
						max = array[j]; 
					}else if(array[j]<min) { // 최소값 구하기
						min = array[j];
					}
				}
				bw.write(min+" "+max);
			}
		}
		br.close();
		bw.flush();
		bw.close();
	}
  • 역시나 입력출력은 buffered 를 활용하였다. 사실 어떤 부분이 가장 어렵게 느껴졌냐면 입력받는 정수의 갯수가 처음 입력했던 정수의 갯수를 따라가야한다는 점이었다. 즉 처음 입력받은 정수의 갯수를 초과하면 꺼지거나 입력을 중단하게 되는 부분을 어떻게 처리해야할까...라는 점에서 고민했던 것 같다.
  • 결국 N 개의 정수를 입력받을 때 입력받은 정수를 split 로 나눠서 tmp 라는 배열에 저장하고 num1(처음 입력받은 정수) 와 tmp 배열의 길이가 동일한지 비교하는 방법으로 문제를 풀어 보았다. 이렇게 되면 num1 보다 더 많은 숫자를 입력했을 때 프로그램이 종료된다.

 

2. 2562번 - 최댓값 찾기

	static void Q_2562() throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

		// 변수 초기화
		int num = 0; // 입력받는 정수
		int[] array = new int[9]; // 9칸을 갖는 배열 생성
		int max = 0; // 최댓값
		int result = 0; // 최댓값 번호

		for(int i=0; i<array.length; i++) { // array 배열 길이만큼 반복
			num = Integer.parseInt(br.readLine()); // 한줄씩 정수 입력받음

			if(num<100) { // 100보다 작을때만 배열에 값 저장
				array[i] = num;

			}else if(num>=100) { // 100보다 큰 경우 배열에 값 저장X 새로 입력받음
				bw.write("100 보다 작은 값을 입력해주세요");
				bw.newLine();
				bw.flush();
				i = i-1;
				continue;
				//				System.exit(0);
			}
		}


		for(int j=0; j<array.length; j++) { // 최댓값과 번호를 구하는 for문

			if(array[j]>max) { // 최대값 구하기
				max = array[j];
			}

			if(array[j]==max) { // 최댓값과 같은 위치의 배열이 확인될때 j 값 확인
				result = j+1; // j+1 하여 result에 저장 +1 하는 이유는 숫자셀때 1부터 세기때문
			}
		}


		bw.write(max+"\n"); // max 값 출력
		bw.write(result+"\n"); // max 값의 배열 번호 출력

		br.close();
		bw.flush();
		bw.close();
	}
  • 최댓값을 찾는 문제는 바로 앞 10818 문제보다는 보다 쉽게 풀었던 것 같다. 그나마 막혔던 부분안 앞의 문제와 마찬가지로 100 보다 큰 숫자를 입력받았을 때 어떻게 할 것인지 정도?
  • 나는 100 보다 큰 숫자를 입력받았을 때 "100보다 작은 값을 입력해주세요" 라고 출력하고, 해당 배열의 순서부터 다시 입력받도록 하였다.

120 을 입력하자 앞의 값은 그대로 두고 새로운 값을 입력받는다

  • 이후 숫자를 다시 입력하면 해당 순서의 숫자부터 배열에 들어가는 것을 확인할 수 있다.

뒤이어 입력한 98 97 96 95 가 정상적으로 배열에 들어갔음을 확인할 수 있다

  • 마지막으로 최댓값의 배열 index 번호인 result 를 +1 하는 이유는 사람이 숫자를 셀 때는 컴퓨터와 다르게 1부터 순서대로 세기 때문에 +1을 하였다. 그냥 result 만하면 그대로 0 부터 순서를 세서 출력하기 때문이다.

 

3. 2577번 - 숫자의 개수

	static void Q_2577() throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

		// 변수 초기화
//		int[] abc = new int[3]; // 입력받은 숫자를 배열로 담음
		int num = 0; // 입력받는 숫자
		int product = 1; // 숫자를 곱한 값 , 초기화를 1로 한 이유는 0 으로주면 뭘 곱해도 0 이기 때문

		int result = 0; // 최종 횟수
		int array[] = new int[10]; // 0 부터 9 까지 몇 번 나오는지 담을 배열


		for(int i=0; i<3; i++) { // abc 배열을 사용한다면 i<abc.length
			num = Integer.parseInt(br.readLine()); 

			if(100<=num && num<1000) { // 입력받는 숫자는 100 이상 1000 미만
//				abc[i] = num;
				product *= num; // 입력받은 값을 바로 product 에 곱함

			}else if(num>=100) { 
				System.exit(0);
			}
		}

		char[] charr = (Integer.toString(product).toCharArray()); 
		// 1. int 형인 product 를 Integer.toString 을 통해 문자열로 변경
		// 2. 문자열.toCharArray() 를 동해 문자형 배열로 변경
		// 최종적으로 charr 에 product 값이 하나하나 배열값으로 담김

		bw.write(Arrays.toString(charr)); // 중간에 곱한 값이 제대로 배열에 들어갔는지 확인하기 위해 출력
		bw.newLine();
		bw.flush();

		for(int q=0; q<10; q++) { // 0 ~ 9 까지 비교
			result = 0; // q 가 1씩 증가할때마다 result 값을 초기화함

			for(int j=0; j<charr.length; j++) { 
				// charr 길이만큼 반복
				// q = 0 일 때 charr.legth 전체만큼 반복 
				// q = 1 일 때 마찬가지

				if((charr[j]-'0')==q) { 
					// charr[j] 값이 q 와 동일할 경우 result +1
					// charr[0] = 0 이고 q = 0 인경우 result +1
					// 이러한 반복을 charr.length 배열의 길이만큼 반복
					result +=1;
				}
				array[q]=result; 
				// 최종적으로 더해진 result 값을 array[q] 번째 값에 담음
				// 이로써 array[0] 즉 0 번째 칸에 0의 갯수인 3이 담김
			}
			bw.write(array[q]+"\n");
			// array[q] 배열의 값을 출력
			// array[0] 이 얼마인지, array[1] 이 얼마인지 출력
			bw.flush();
		}
		br.close();
		bw.flush();
		bw.close();
	}
  • 난이도는 분명 2562 번이 더 어려운 것으로 나오는데(정답률) 이상하게 나는 10818 ~ 2577 중에서는 2577 번이 가장 어려웠다. 다만 이 부분은 내가 Buffered 로 받아서 그런 것이라고 생각한다. scan 으로 받으면 이렇게 저렇게 형변환할 필요없이 바로 계산하기 쉬운데 비해 buffered 로 입력받으면 String 이 기본형이라...많이 고쳐야한다.
  • 풀이방법은 직접 코드에 설명을 써두었으니 그 부분을 보는게 더 빠를 듯하다. 여기서부터 적는 것은 부가적인 부분들 + 내가 기억해야하는 부분들이다.

1) int[] abc 란 배열을 변수로만 잡아두고 따로 사용하지 않은 이유

  • 잠깐 보면 알겠지만 처음에는 abc 배열을 사용하여 입력받은 숫자 num 을 abc 배열에 두고 해당 배열의 값을 꺼내와서 곱한다는...듣기만해도 복잡한 생각을 했었다.
  • 그러다가 문득 굳이 그렇게? 라는 생각이 들었고, abc 배열을 없애고 그냥 입력받은 값을 100 이상 1000 미만인지만 검사하여 그 값을 바로 product 라는 값에 곱해버리는 방법을 사용하였다. 내가 생각했을 땐 훨씬 덜 복잡해진 듯 하다.
  • product 를 0 이 아닌 1로 초기화하는 이유는 product 에 계속 곱해서 들어갈 것이기 때문에 0 으로 초기화하면 그냥 최종값도 0 이 되버려서 초기치를 1로 두기로 하였다.
############# 변경 전 ##############

		int[] abc = new int[3]; // 입력받은 숫자를 배열로 담음
		int num = 0; // 입력받는 숫자
		int product = 1; // 숫자를 곱한 값 , 초기화를 1로 한 이유는 0 으로주면 뭘 곱해도 0 이기 때문

		int result = 0; // 최종 횟수
		int array[] = new int[10]; // 0 부터 9 까지 몇 번 나오는지 담을 배열


		for(int i=0; i<abc.length; i++) { // abc 배열을 사용한다면 i<abc.length
			num = Integer.parseInt(br.readLine()); 

			if(100<=num && num<1000) { // 입력받는 숫자는 100 이상 1000 미만
				abc[i] = num;
				product *= abc[i]; // 입력받은 값을 바로 product 에 곱함

			}else if(num>=100) { 
				System.exit(0);
			}
		}
        
        
 ############## 변경 후 ##############
 
		int num = 0; // 입력받는 숫자
		int product = 1; // 숫자를 곱한 값 , 초기화를 1로 한 이유는 0 으로주면 뭘 곱해도 0 이기 때문

		int result = 0; // 최종 횟수
		int array[] = new int[10]; // 0 부터 9 까지 몇 번 나오는지 담을 배열


		for(int i=0; i<3; i++) { // abc 배열을 사용한다면 i<abc.length
			num = Integer.parseInt(br.readLine()); 

			if(100<=num && num<1000) { // 입력받는 숫자는 100 이상 1000 미만
				product *= num; // 입력받은 값을 바로 product 에 곱함

			}else if(num>=100) { 
				System.exit(0);
			}
		}

 

2) charr 배열 부분

  • 이 부분은 내가 Buffered 로 입력을 받고 그걸 다시 int형으로 바꾸어 product 에 저장하였기 때문에 사용한 구문이다. 
  • 첫째줄부터 product를 Integer.toString 이라는 Integer 의 매소드를 사용하여 String 형태로 변환한다.
  • 다음으로 str 을 toCharrArray() 라는 매소드를 사용하여 charr 이라는 char 형 배열에 저장하는 것을 합쳐서
  • 맨 아랫줄 char[] charr = (Integer.toString(product).toCharArray()); 를 사용한 것이다.

 

String str = Integer.toString(product); 
// 1. int 형인 product 를 Integer.toString 을 통해 문자열로 변경

char[] charr = str.toCharArray(); 
// 2. 문자열.toCharArray() 를 동해 문자형 배열로 변경

를 아래처럼 하나로 합칠 수 있다.

char[] charr = (Integer.toString(product).toCharArray()); 
// 최종적으로 charr 에 product 값이 하나하나 배열값으로 담김

 

3) for 2중 반복문 및 if 문

		for(int q=0; q<10; q++) { // 0 ~ 9 까지 비교
			result = 0; // q 가 1씩 증가할때마다 result 값을 초기화함

			for(int j=0; j<charr.length; j++) { 
				// charr 길이만큼 반복
				// q = 0 일 때 charr.legth 전체만큼 반복 
				// q = 1 일 때 마찬가지

				if((charr[j]-'0')==q) { 
               		// 문자형 - '0' = 숫자형
					// charr[j] 값이 q 와 동일할 경우 result +1
					// charr[0] = 0 이고 q = 0 인경우 result +1
					// 이러한 반복을 charr.length 배열의 길이만큼 반복
					result +=1;
				}
				array[q]=result; 
				// 최종적으로 더해진 result 값을 array[q] 번째 값에 담음
				// 이로써 array[0] 즉 0 번째 칸에 0의 갯수인 3이 담김
			}
			bw.write(array[q]+"\n");
			// array[q] 배열의 값을 출력
			// array[0] 이 얼마인지, array[1] 이 얼마인지 출력
			bw.flush();
		}
  • 여기는 코드에 적어둔 주석문을 함께 보는게 훨씬 이해가 쉬울 것이라고 생각한다.
  • 먼저 첫번째 for 문은 숫자 0 부터 9 까지 비교하기위해 반복되는 for 문이다.
  • 다음 for 문은 charr 배열의 전체를 첫번째 for 문의 변수인 q와 돌아가면서 비교하기 위해서 사용되는 for 문이다.
  • 중간에 사용되는 if 문은 charr[j]-'0' 하여 charr[j] 의 값을 int 형으로 형변환 한 뒤 q 값과 비교하기 위해 사용된다. 만약 charr[j] 값이 q 와 동일하다면 result 값에 +1 을 한다.
  • 최종적으로 charr 배열의 길이만큼 반복되어 더해진 result 값을 array 배열의 q 번째 값에 저장한다. 이는 array[0] 번째 값에 0 이 몇번이나 있는지 확인 후 더해진 result 값을 저장하는 것이다.
  • 이후 array[q] 의 값을 bw.write 를 통해 출력한다.

 

이번 문제들은 죄다 조금씩 고민해서 풀었던 것 같다. 그래도 내가 애먹었던 문제들을 결국에는 풀어내는 것이 예전에 학교다니면서 수학공부할 때 생각도 나고ㅋㅋ은근히 재밌기도해서 시간 가는 줄 모르고 풀었던 것 같다. 덕분에 오늘 java 강의는 날려먹었지만...ㅠㅠ

댓글