정보처리 산업기사 실기

100개의 수 중 77에 가장 가까운 수를 구하는 알고리즘 순서도

유혁스쿨 2021. 3. 9. 19:19
728x90
반응형

제시된 <그림>은 배열 GK에 저장되어 있는 100개의 수 중 77에 가장 가까운 수를 구하는 알고리즘을 나타낸 것 이다.

<처리조건>에 따라 가장 효율적인 알고리즘으로 구현될 수 있도록 <그림>의 괄호 ()~()에 해당하는 답을 쓰시오.

<처리조건>

˙배열의 크기가 N일 경우 배열의 요소는 1부터 N까지이다.

˙배열 GK(100)의 각 요소에는 임의의 값이 저장되어 있는 것으로 가정한다.

˙변수 설명

 - CHA : 77과 비교 대상의 차이 값이 저장될 변수

 - FGK : 77과 가장 가까운 값이 저장될 변수

 - N : 배열 GK의 위치를 지정해 주는 변수

 - COMP : 77과 비교 대상의 차이 값 중 최소값이 저장될 변수

 

길이가 100인 배열 GK에서 값을 하나씩 뽑아 비교하는 내용의 순서도이다

 

배열 GK의 위치를 지정해 줄 변수 N을 0값을 저장한다.

77과 비교 대상의 차이값이 저장 될 변수 COMP에 300값을 저장한다.

 

이후 N에 어떠한 값인  ①번이 저장된다

순서도를 멀리 봤을때 특정 조건이 성립되면 다시 돌아와 반복하는 알고리즘 이며

해당 조건은 N이 100보다 작다는 N<100의 식이 성립됬을때 돌아온다.

변수 N의 초기값으로 0을 저장했기 때문에 마지막 조건 N<100 이 있음을 확인 즉, N은 증가되야함을 유추할수 있다.

그러므로 ①번은 N+1이 된다.

 

 

GK의 N번째인덱스 값이 77보다 크다면 혹은 작다면 두가지의 경우로 나뉘게 되며

이때, 두가지의 각 경우별로 변수 CHA에 어떠한 값이 저장 된다.

 

처리조건상 CHA는 77과 비교대상의 차이 값이 저장될 변수이며 비교 대상은 GK(N) 이므로

 

GK(N)보다 77이 크다는 조건이 참일때 CHA값에 처리조건에 성립하는 값을 저장한다.

이때 GK(N)은 77보다 크므로 GK(N)에서 77값을 뺀 차이값을 CHA에 저장해준다.

즉, ③번에 들어갈 답은 GK(N) - 77이 된다.

 

반대로 GK(N)보다 77이 크다는 조건이 거짓일 경우에도 변수 CHA에 처리조건에 성립하는 값을 저장한다.

이때 GK(N)은 77보다 작으므로 77에서 GK(N)값을 뺀 차이값을 CHA에 저장해준다.

즉, ②번에 들어갈 답은 77 - GK(N)이 된다.

 

 

다음 순서로 77과 비교대상의 차이 값중 최소값 이 저장될 변수 COMP가 CHA와 크기비교가 된다.

이때 말하는 차이값은 바로 이전 순서에서 번 두 차이값 을 뜻한다.

COMP가 CHA보다 클 경우 CHA를 ④번에 저장한다.

현재는 변수 COMP의 초기값이 300으로 저장되어있기 때문에 처음 로직을 돌렸을 경우 2번 혹은 3번 보다 값이 크다

때문에 다음 순서인 CHA값을 번에 저장하는것이 맞다.

그렇다면 은 무엇일까?

최소값 COMP와 CHA값을 비교 한 후 CHA값이 COMP보다 크지 않으면 CHA값을 번에 저장하기 때문에 최소값을 초기화하는 로직이 된다.

최소값보다 작은 값을 어딘가에 저장한다? 라는 의문을 가져보게 되면 최소값보다 작은 값은 최소값이 되므로 최소값을 담는 변수 COMP에 값을 저장해야 한다는 것을 유추할 수 있다.

때문에 ④은 최소값인 COMP가 된다.

 

 

다음 순서에는 77과 가장 가까운 값이 저장될 변수 FGK에 어떠한 값인 번이 저장된다.

이 값은 처리조건상 77과 가장 가까운 값이 저장되므로 77과의 차이중의 최대값 즉 CHA의 값들 중 최대값을 저장해야한다.

77과 가장 가까운 값은 76,78 이기 때문에 CHA값이 작을수록 원하는 결과값에 근접해진다.

즉 GK(N)이 76혹은 78이 되어야 CHA값이 작아진다.

 

FGK에는 77과 가장 가까운 값이 저장되야 하므로 문제에서 제시 한 대로 GK 배열 중의 어떠한 인덱스 값들 중 하나를 저장 해 줘야 한다

그 값이 크든 작든 76혹은 78과 가깝든 멀든 GK(N)을 저장해 줘야한다.

따라서 ⑤번에는 GK(N)이 저장된다.


자바 로직 으로 짜봤다.

import java.util.Arrays;

public class Algori {
	 public static void main(String[] args) {
		 int [] gk = new int[100];
		 
		 int cha, fgk;
		 
		 int n = 0, comp = 300;
		 
		 do {
			n++;
			if(gk[n]>77) {
				cha = gk[n] - 77;
			}else {
				cha = 77 - gk[n];
			}
			if(comp>cha) {
				comp = cha;
			 	fgk = gk[n];
				 
			}else {
				continue;
			} 

			 System.out.println(fgk);
		 }		 
		 while(n<100);
		
		
		
	}
	

}

순서도에 따라 do while문으로 진행했다.

 

 

현재 로직상으로 배열이 비어있는 상태이므로 Math.random() 함수를 통해 배열에 1부터 100까지의 난수를 넣어보았다.

import java.util.Arrays;

public class Algori {
	 public static void main(String[] args) {
     
		 //gk 배열을 선언만 했으므로 빈 배열인 상태.
		int [] gk = new int[100];
		          
         //배열에 난수 저장하는 로직. 
		 for(int i=0; i < gk.length; i++) {
			gk[i] = (int)(Math.random()*100+1); 
		 }
		 System.out.println("gk 배열 원소"+Arrays.toString(gk));

	}
}

 

이때, GK 배열의 원소 값들에 중복이 생긴다.

 

때문에 중복을 제거하는 로직을 따로 짜 보았다.

 

import java.util.Arrays;

public class Algori {
	 public static void main(String[] args) {
     
		 /*
		 for(int i=0; i < gk.length; i++) {
			gk[i] = (int)(Math.random()*100+1); 
		 }
		 System.out.println("gk 배열 원소"+Arrays.toString(gk));
		 */
         
		 //배열에 중복을 제거한 난수 저장하기
		 for(int i=0; i < gk.length; i++) {
			 gk[i] = (int)(Math.random()*100+1); 
			 for(int j = 0; j < i; j++) {
				 if(gk[i] == gk[j]) {
					 i--;
					 break;
				 }
			 }
		 }
		 System.out.println("gk 배열 원소"+Arrays.toString(gk));
		
	}
}

 

 

import java.util.Arrays;

public class Algori {
	 public static void main(String[] args) {
		 int [] gk = new int[100];

		 //배열을 선언만 했으므로 배열에 중복을 제거한 난수 저장하기
		 for(int i=0; i < gk.length; i++) {
			 gk[i] = (int)(Math.random()*100+1); 
			 for(int j = 0; j < i; j++) {
				 if(gk[i] == gk[j]) {
					 i--;
					 break;
				 }
			 }
		 }
		 System.out.println("gk 배열 원소"+Arrays.toString(gk));
		 
		 int cha, fgk;
		 
		 int n = 0, comp = 300;
		 
		 do {
			n++;

			 if(gk[n]>77) {
				 cha = gk[n] - 77;
			 }else {
				 cha = 77 - gk[n];
			 }
			 if(comp>cha) {
				comp = cha;
				 fgk = gk[n];
				 
			 }else {
				 continue;
			 } 

			 System.out.println(fgk);
			 System.out.println("현재 배열 GK의 인덱스 n의 값"+n);
		 }		 
		 while(n<100);
		
	}

}

로직에 문제가 발생한다

do while문은 조건절이 무조건 한번 실행 하기 때문에 n의 값이 0부터가 아닌 1부터 시작하게 된다.

gk배열의 길이가 100일때 자바의 배열에서 인덱스는 0부터 99까지로 100개가 존재한다.

때문에 배열의 크기가 N일 경우 배열의 요소는 1부터 N까지 라는 처리조건과 맞지 않게 된다.

인덱스를 1부터 시작하게되면 100개까지의 마지막이 101이 되기 때문에 길이가 100인 배열의 101번째 인덱스를 검색하도록 실행되기 때문에

콘솔창에 Eception in thread "main" java.lang.ArrayIndexOutOfBoundsException:100 이라는 오류메시지가 뜬다.

 


		 
		 do {
   			n++; //이곳에 놓게되면
			 if(gk[n-1]>77) { //배열 인덱스에서 n-1을 해줘야 범위가 성립된다
				 cha = gk[n] - 77;
			 }else {
				 cha = 77 - gk[n-1]; //n-1
			 }
			 if(comp>cha) {
				comp = cha;
				 fgk = gk[n-1]; //n-1
				 
			 }else {
				 continue;
			 } 

			 System.out.println(fgk);

		 }		 
		 while(n<100);

혹은 처음에는 0부터 시작하여 continue가 되기 이전에 n++ 즉 증가 시켜준다.


		 do {

			 if(gk[n]>77) {
				 cha = gk[n] - 77;
			 }else {
				 cha = 77 - gk[n];
			 }
			 if(comp>cha) {
				comp = cha;
				 fgk = gk[n];
				 
			 }else {
				n++; //continue 이전에 증가
				continue;
			 } 

			 System.out.println(fgk);
		 }		 
		 while(n<100);


일반 while반복문 

import java.util.Arrays;

public class Algori {
	 public static void main(String[] args) {
		 int [] gk = new int[100];
		 
		 //배열을 선언만 했으므로 배열에 중복을 제거한 난수 저장하기
		 for(int i=0; i < gk.length; i++) {
			 gk[i] = (int)(Math.random()*100+1); 
			 for(int j = 0; j < i; j++) {
				 if(gk[i] == gk[j]) {
					 i--;
					 break;
				 }
			 }
		 }
		 System.out.println("gk 배열 원소"+Arrays.toString(gk));
		 
		 
		 int cha, fgk = 0;
		 
		 int n = 0, comp = 300;
		 
		 while(n<100) {
			 n++;
			 if(gk[n]>77) {
				 cha = gk[n] - 77;
			 }else {
				 cha = 77 - gk[n];
			 }
			 if(comp>cha) {
				comp = cha;
				 fgk = gk[n];
			 }else {
				 continue;
			 }
				 System.out.println(fgk);
			 } 
		 }
		
}
	


구독과 공감 혹은 댓글이 블로거에게는 큰 힘이 됩니다.

728x90
반응형