정리 노트/쌍용 KDT_(자바 Spring)

23.02.08(수): 반복문 (while, do-while, for) + 다중 for문

우주바다 2023. 2. 27. 22:53
728x90

오늘 배운 것
01.  while   
02.  do-while
03.  for

- 다중 for문



01.  while   

 

실습 052

정수 2개를 입력받고, 작은 수부터 큰 수까지 누적합을 구하고 출력.

 

2/8 내 코드

더보기
// 2/8 내 코드 
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

System.out.print("첫 번째 정수 입력: ");
int a = Integer.parseInt(br.readLine());
int oa = a;  // 출력문에 쓸 a의 원본 값 

System.out.print("두 번째 정수 입력: ");
int b = Integer.parseInt(br.readLine());
int ob = b;  // 출력문에 쓸 b의 원본 값

if (a < b){
	int sum = a;     // 합계를 지역변수로 따로 선언
	while(a < b){    // 합계를 a로 초기화했으므로 b-1 만큼 반복 
		sum += a + 1 ;
		a ++;
	}
	System.out.printf("%d ~ %d 까지의 합: %d\n", oa,b,sum);
}
else if (a > b) {    // 두 번째 수가 더 작을 때 
	int sum = b;     // 합계를 b를 기준으로 바꾸고
	while(b < a){    // 이후 연산도 b 기준.
		sum += b + 1 ;
		b ++;
	}
	System.out.printf("%d ~ %d 까지의 합: %d\n", ob,a,sum);
}
else{
	System.out.println("입력값 오류입니다.");
}

단순하게 누적합 연산을 먼저 설계하고 나니 출력문에서 원본 값이 필요했다.

흘러가는 대로 작성하면서 비효율적이고 복잡한 코드가 되었다.

가볍게 훑어봤을 때 별로 좋아 보이지 않아서 바로 백지 복습했다.

// 2/26 백지 복습
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("첫 번째 정수 입력: ");
int n1 = Integer.parseInt(br.readLine()); // 입력값 1
System.out.print("두 번째 정수 입력: ");
int n2 = Integer.parseInt(br.readLine()); // 입력값 2

// 입력값 대소 비교. n1이 더 크면 Swap
if (n1 > n2)  
{
	int tmp = n1; 
	n1 = n2;
	n2 = tmp; 
}

int n = n1; // 루프 변수(n1으로 초기화)
int sum = 0; // 누적합
while(n <= n2) //n2가 될때까지 누적합
{
	sum += n; 
	n++;
}
// 출력
System.out.printf("%d ~ %d까지의 합: %d\n" ,n1,n2,sum);


설계 포인트
: 입력값 대소비교 선행 -> 누적합 진행 후 출력. 

이전 코드와 차이점: 
출력을 위해 원본값 필요. 어차피 작은 수를 루프변수로 활용하면 따로 원본 값 변수 필요함. 
따라서 n1, n2 만 선언하지 않고 따로 루프변수를 둠.

// su1이 더 큰 경우 swap
if ( su1 > su2 )
{
	su1 = su1^su2; // 배타적 논리합
	su2 = su2^su1;
	su1 = su1^su2; 
}

복습 후, 강사님 코드와 비교. 

다른 부분은 swap이었다. 비트연산자로 시간효율을 높이기. 


실습 053 (과제)

정수를 입력 받아 1부터 입력값까지의 전체 합, 짝수의 합, 홀수의 합을 각각 출력

 

2/8 내 코드

더보기
// 2/8 코드 상하략
int n = 1;	// 루프 변수이자 1부터 증가할 값
int num = Integer.parseInt(br.readLine());// 입력값 
int sum = 0, evenSum = 0, oddSum = 0;   // 전체 합 짝수 합, 홀수 합 

while (n <= num) 
{
	sum += n;           // 전체 합산
	if (n % 2 == 0)		
		evenSum += n;	//짝수 합
	else				
		oddSum += n;	// 홀수 합 
	n++;				// n 증가 
}
System.out.println(">> 전체 합: " + sum);
System.out.println(">> 짝수 합: " + evenSum);
System.out.println(">> 홀수 합: " + oddSum +"\n");

2/26  복습 코드

// 2/26 복습(상하략)
int max = Integer.parseInt(br.readLine()); //입력값
int n = 1; // 루프 변수  
int oddSum = 0, evenSum = 0, totSum = 0; // 홀수,짝수,전체(누적합이므로 초기화 필수) 

while (n <= max) //1부터 max까지 누적합
{
	totSum += n; // 전체합
	if (n % 2 != 0)
		oddSum += n; // 홀수 합
	else
		evenSum += n; // 짝수 합
	n++; //루프변수 증가
}		
System.out.println("1 ~ "+ max +" 까지의");	
System.out.printf( ">>홀수 합: %d\n>>짝수 합: %d\n>>전체 합: %d\n", oddSum, evenSum, totSum);

변수 이름을 더 명확하게 하고, 출력문에서 중복되는 부분을 분리해서 작성했다.


실습 054

구구단 중 원하는 단을 사용자 입력받고 출력.

값이 1~9 범위가 아니라면 안내 후 프로그램 종료

더보기
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("원하는 단 입력: ");
int num = Integer.parseInt(br.readLine()); // 사용자 입력값
int n = 1;     // 1부터 9까지 곱할 때 쓸 루프 변수

if ( 1 > num || num > 9 )  //1보다 작거나 9보다 큰 경우 
	System.out.println(" 1부터 9까지의 정수만 입력 가능합니다.");
	return; // 메소드 종료 
else{
	while(n <= 9){
		System.out.printf("%d * %d = %d\n", num , n, (num * n));
		n ++ ;
	}
}// 상하략

02.  do-while

 

○ 특징

while문과 다르게 반드시 1회 실행을 보장한다.

조건식 검사를  최초 1회 수행 이후 진행한다.

 

○ 형식 및 구조

do
{
	실행문;
}
while(조건식);

실습 055

int n = 0;
do 
{	
	System.out.println("n =" + ++n );
}
while (n < 10);

루프 변수 증가와 출력을 한 번에 수행. 

int num;
do
{
  System.out.print("100 이상의 정수를 입력하세요: ");
  num = sc.nextInt();
}
while (num < 100);
System.out.println("\n" + num + "100 이상의 정수 입력 완료!");

입력값 검사에 활용한 예시. 


실습 056 + 056_1

양의 정수를 n번 입력받고, 총합 출력.

단, -1 이 입력되면 반복을 중지하고 누적합을 출력한다. ( -1을 입력 중지 커맨드로 활용 )

+) 음수 입력값 예외처리 (과제)

 

2/8 코드(과제)

더보기
System.out.println("[ 양의 정수를 입력하세요 (중지하려면 -1을 입력) ]");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

int n = 1 ;   // 순번 (출력용)
int num;     // 입력값
int sum = 0;  // 합계 결과

do
{	System.out.print(n+"번째 정수 입력: "); 
	n++;								 // 순번 증가 
	num = Integer.parseInt(br.readLine()); // 입력값
	sum += num;							 // 값 누적하기
	
	if (num < -1 ){ // -1 제외 음수 입력시
		sum -= num; // 합산에서 제외
		System.out.println("---[안내] 음수는 결과 값에서 제외됩니다.---");
	}
}
while(num != -1); // -1 을 입력받을 때까지 반복 		
System.out.println("\n>> 현재까지 입력된 정수의 합: " + (sum + 1)); // 중지 값 복구 	
}

2/26 코드

0은 누적할 필요가 없고 양의 정수가 아니니 따로 분기 처리 하고, 안내 문구와 개행을 추가했다.

더보기
System.out.println("양의 정수를 입력하세요.(중지하려면 -1을 입력)");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));	

int n = 0;   // 출력 루프 변수
int num;     //사용자 입력
int sum = 0; // 누적합

do
{	
	System.out.printf("%d번째 정수 입력:", ++n);
	num = Integer.parseInt(br.readLine());

	if(num == 0 || num <-1)// 0이거나 음수(-1제외)
	{	
		--n; //출력 번호 
		System.out.println("\n양의 정수를 입력하거나 -1로 종료하세요!");
	}		
	else if(num > 0)//양의 정수일때만 누적합
	{
		sum += num; 
	}
}
while (num != -1);
System.out.println("\n====[입력을 종료합니다.]====");
System.out.println(">> 입력된 정수의 총합: " + sum);​

03.  for

 

○ for 문  

while문과 마찬가지로 한 번도 실행되지 않을 수 있다.

루프 변수의 초기값, 조건식, 증감식 등을 한 번에 확인할 수 있어 가독성이 좋다.

 

○ 형식 및 특징

  for(수식1; 수식2; 수식3;)
  {
  	실행문;
  }​

 

 수식 1은 변수 초기화에 사용되며 최초 1회만 실행한다.

 수식 2는 조건식으로, true인 동안 반복한다.
 수식 3는 루프 변수를 재초기화한다.
조건식(수식2)을무너뜨리는 증감식을 일반적으로 사용한다.
, (콤마)를 통해 여러 문장을 동시에 수행할 수 있으며, 각 수식은 생략 가능하다.


실습 057

int n = 1, m = 1; // while, for의 루프 변수
while (n <= 10)
{	System.out.println("n =" + n);
	n++;
}
/*-- 위 while문을 for문으로 바꾸기 --*/
for (m =1; m <=10 ; m++)
	System.out.println("m =" + m);
for (m =0; m <10 ; m++)
	System.out.println("m =" + m);

실습 058

1 ~100 범위 정수에서 4의 배수만 출력. 단, 한 줄에 5개씩만 출력한다. 

for문 기본 실습_ 항상 시공간 복잡도를 고려하자!


실습 059

다중 for문을 통한 구구단 출력


실습 060

다중 for문(중첩)을 통한 구구단 출력 
hint : 3 중첩 반복문 1개, 또는 2 중첩 반복문 2개를 활용할 수 있다. 

실행 예시

중첩 for문 2개 

for (int i = 1; i <= 9 ; i++){// 곱해지는 1 ~ 9
	for (int j = 2; j <= 5; j++){// 2단 ~ 5단 
		System.out.printf("%3d * %d = %3d   ", j, i, ( j * i));	
	}
	System.out.println();
}
System.out.println();  // 중간 개행 
for (int i = 1; i <= 9 ; i++){	
	for (int j2 = 6; j2 <= 9; j2++){// 6단 ~ 9단 
		System.out.printf("%3d * %d = %3d   ", j2, i, ( j2 * i));
	}
	System.out.println();
}// 상하략

 

3중첩 for문 3개 (강사님 코드)

처음에 혼자 만드는데 실패했던.. 3 중첩. 단계별로 알려주셔서 좋았다.

읽어서 이해하는 데는 무리가 없지만, 막상 백지 복습하려고 하면 바로 떠오르진 않는다..

익숙해질 때까지는 지속적인 복습이 필요할 것 같다.

더보기
for (int h = 0; h <= 1 ; h++)//0~1 (2회 루프)
{
	for(int i = 1; i<= 9; i++) // 웅 ~ 곱해지는 수 1부터 9 
	{ 
		for (int j = 2; j<= 5; j++ ) // 숑! 2단 ~ 5단 
		{
			System.out.printf("%4d * %d = %2d", j+(h*4), i, ((j+(h*4)) * i));  
		}	//---> 두 번째 루프에서 단수를 4씩 증가, 결과값 부분도 변경.
		System.out.println(); //개행 
	}
	System.out.println(); //개행 
}// 상하략

 

혼자 구현하는데 실패했던 예제.

생각을 끝까지 마치고 한 번에 완성하려는 버릇 때문에 더 그랬다.

우선 부분적인 기능이나 틀부터 구현하고 하나씩 고쳐야겠다. 

 

단계별로 살펴보기 (복습용)

더보기
/* ------------------------------ 단계별로 살펴보기 ----------------------------

4개 단을 출력하는 아래의 for구문을

for(int i = 1; i<= 9; i++) // 웅 ~ 곱해지는 수 1부터 9 
		{ 
			for (int j = 2; j<= 5; j++ ) // 숑! 2단 ~ 5단 
			{
				System.out.printf("%4d * %d = %2d" ,j ,i, (j*i));
			}
			System.out.println(); //개행 (한 단이 끝날 때) 
		}
------------------------------------------------------------------------------------------
 2번 반복하는 outer for문을 만들어서

for (int h = 0; h <= 1 ; h++) // 1회 루프 : h = 0  → 2회 루프  h = 1
{
			
}
---------------------------------------------------------------------------------------------------
그 안에 넣으면?!		
for (int h = 0; h <= 1 ; h++)
{
	for(int i = 1; i<= 9; i++) // 웅 ~ 곱해지는 수 1부터 9 
	{ 
		for (int j = 2; j<= 5; j++ ) // 숑! 2단 ~ 5단 
		{
			System.out.printf("%4d * %d = %2d" ,j ,i, (j*i));
		}
		System.out.println(); //개행 
	}
	System.out.println(); //개행 
}
// 여기까지 출력결과

   2 * 1 =  2   3 * 1 =  3   4 * 1 =  4   5 * 1 =  5
   2 * 2 =  4   3 * 2 =  6   4 * 2 =  8   5 * 2 = 10
   2 * 3 =  6   3 * 3 =  9   4 * 3 = 12   5 * 3 = 15
   2 * 4 =  8   3 * 4 = 12   4 * 4 = 16   5 * 4 = 20
   2 * 5 = 10   3 * 5 = 15   4 * 5 = 20   5 * 5 = 25
   2 * 6 = 12   3 * 6 = 18   4 * 6 = 24   5 * 6 = 30
   2 * 7 = 14   3 * 7 = 21   4 * 7 = 28   5 * 7 = 35
   2 * 8 = 16   3 * 8 = 24   4 * 8 = 32   5 * 8 = 40
   2 * 9 = 18   3 * 9 = 27   4 * 9 = 36   5 * 9 = 45

   2 * 1 =  2   3 * 1 =  3   4 * 1 =  4   5 * 1 =  5
   2 * 2 =  4   3 * 2 =  6   4 * 2 =  8   5 * 2 = 10
   2 * 3 =  6   3 * 3 =  9   4 * 3 = 12   5 * 3 = 15
   2 * 4 =  8   3 * 4 = 12   4 * 4 = 16   5 * 4 = 20
   2 * 5 = 10   3 * 5 = 15   4 * 5 = 20   5 * 5 = 25
   2 * 6 = 12   3 * 6 = 18   4 * 6 = 24   5 * 6 = 30
   2 * 7 = 14   3 * 7 = 21   4 * 7 = 28   5 * 7 = 35
   2 * 8 = 16   3 * 8 = 24   4 * 8 = 32   5 * 8 = 40
   2 * 9 = 18   3 * 9 = 27   4 * 9 = 36   5 * 9 = 45
계속하려면 아무 키나 누르십시오 . . .

-------------------------------------------------------------------------------------------------
같은 구문을 두 문단으로 나누어 처리할 때 
문단에 따라 다르게 주어지는 환경(h의 값)을 활용.

public class Test060_2
{
	public static void main(String[] args){

		for (int h = 0; h <= 1 ; h++)
		{
			for(int i = 1; i<= 9; i++) // 웅 ~ 곱해지는 수 1부터 9 
			{ 
				for (int j = 2; j<= 5; j++ ) // 숑! 2단 ~ 5단 
				{
					System.out.printf("%4d * %d = %2d" ,j + (h*4) ,i, (j*i)); 
				} //--> 두 번째 루프에서 단수를 4씩 증가해서 출력 
				System.out.println(); //개행 
			}
			System.out.println(); //개행 
		}
	}				
}
------------여기까지 출력 : 단만 바뀌고 연산 결과는 바뀌지 않았음 ------------
   2 * 1 =  2   3 * 1 =  3   4 * 1 =  4   5 * 1 =  5
   2 * 2 =  4   3 * 2 =  6   4 * 2 =  8   5 * 2 = 10
   2 * 3 =  6   3 * 3 =  9   4 * 3 = 12   5 * 3 = 15
   2 * 4 =  8   3 * 4 = 12   4 * 4 = 16   5 * 4 = 20
   2 * 5 = 10   3 * 5 = 15   4 * 5 = 20   5 * 5 = 25
   2 * 6 = 12   3 * 6 = 18   4 * 6 = 24   5 * 6 = 30
   2 * 7 = 14   3 * 7 = 21   4 * 7 = 28   5 * 7 = 35
   2 * 8 = 16   3 * 8 = 24   4 * 8 = 32   5 * 8 = 40
   2 * 9 = 18   3 * 9 = 27   4 * 9 = 36   5 * 9 = 45

   6 * 1 =  2   7 * 1 =  3   8 * 1 =  4   9 * 1 =  5
   6 * 2 =  4   7 * 2 =  6   8 * 2 =  8   9 * 2 = 10
   6 * 3 =  6   7 * 3 =  9   8 * 3 = 12   9 * 3 = 15
   6 * 4 =  8   7 * 4 = 12   8 * 4 = 16   9 * 4 = 20
   6 * 5 = 10   7 * 5 = 15   8 * 5 = 20   9 * 5 = 25
   6 * 6 = 12   7 * 6 = 18   8 * 6 = 24   9 * 6 = 30
   6 * 7 = 14   7 * 7 = 21   8 * 7 = 28   9 * 7 = 35
   6 * 8 = 16   7 * 8 = 24   8 * 8 = 32   9 * 8 = 40
   6 * 9 = 18   7 * 9 = 27   8 * 9 = 36   9 * 9 = 45

-----------------------------------최종결과 -------------------------------
public class Test060_2{
	public static void main(String[] args){
		for (int h = 0; h <= 1 ; h++)
		{
			for(int i = 1; i<= 9; i++) // 웅 ~ 곱해지는 수 1부터 9 
			{ 
				for (int j = 2; j<= 5; j++ ) // 숑! 2단 ~ 5단 
				{
					System.out.printf("%4d * %d = %2d" ,j + (h*4) ,i ,((j + (h*4)) * i)); 
				}   //---> 두 번째 루프에서 단수를 4씩 증가, 결과값 부분도 변경. 
				System.out.println(); //개행 
			}
			System.out.println(); //개행 
		}
	}				
}

오늘 느낀 점
while, do-while에 비해 익숙한 for문은 비교적 쉬울 줄 알았다.. 
하지만 파이썬 기초 문법으로 쉬운 난이도 코테만 풀어봐서 그런 지 3 중첩이 어려웠다.
특히 코테에서는 루프 중첩은 시간복잡도 때문에 가능한 지양하는 편이 좋다고 들어서 2중첩 이상은 써 본 적이 거의 없었다.

4 중첩 이상 쓸 일은 별로 없겠지만 3 중첩까지는 많이 쓸 테니 자주 복습해야겠다.

728x90
반응형