조컴퓨터

200820 OOP 06 - Java For, Array 본문

자바 웹개발자 과정/JAVA

200820 OOP 06 - Java For, Array

챠오위 2020. 8. 27. 09:51

② 반복문 - for문

프로그램을 작성하다 보면 똑같은 실행문을 반복적으로 실행해야 할 경우가 많이 발생하는데 이런 경우에 사용하는 것이 반복문이다.

반복문은 한 번 작성된 실행문을 여러 번 반복 실행해주기 때문에 코드를 절감하고 간결하게 만들어준다. for문은 주어진 횟수만큼 실행문을 반복 실행할 때 적합한 반복 제어문이다.

 

초기값의 역할은 조건식과 실행문, 증감에서 사용할 변수를 초기화하는 역할을 한다. 

 

for(초기값; 종료값; 증감)
//for(;;) { } → 무한 루프

 

for(int a=1; a<=3; a=a+1) {		//for 내부에서 선언된 a값은 함수 안에서만 사용 가능 (지역 변수)
	System.out.println("JAVA");
	System.out.println(a);
}//for end

/*
	JAVA
	1
	JAVA
	2
	JAVA
	3
*/

 

 

어떤 경우에는 초기값이 둘 이상이 있을 수도 있고, 증감도 둘 이상이 있을 수 있다. 이런 경우에는 쉼표(,)로 구분해서 작성하면 된다.

 

for(int i=0, j=10; i<=10 && j>=0; i++, j--) { }

 

초기값에 선언된 변수는 for문 블록 내부에서 사용되는 지역 변수이다. 따라서 for문을 벗어나서는 사용할 수 없다.

 

for(int a=1; a<=3; a=a+1) {
	System.out.println("JAVA");
	System.out.println(a);
}//for end
System.out.println(a);			//에러

 

 

유효범위 SCOPE

변수: 선언 위치에 따라 전역 변수와 지역 변수로 나뉜다.

전역 변수 global variable: 전체에서 어디서든 호출하면 사용할 수 있는 변수

지역 변수 local variable  : 특정한 구역( { } ) 안에 생성되어 그 지역 안에서만 사용할 수 있는 변수

 

 

감소에 따른 반복

 

int b;		//전역 변수
for(b=3; b>=1; b=b-1) {
	System.out.println("Python");
}//for end
		
System.out.println(b);

/*
	Python
	Python
	Python
	0
*/

 

 

이중반복문

for문은 또 다른 for문을 내포할 수 있는데, 이것은 중첩된 for문이라 한다. 이 경우 바깥쪽 for문이 한 번 실행될 때마다 중첩된 for문은 지정된 횟수만큼 반복해서 돌다가 다시 바깥쪽 for문으로 돌아간다.

 

 

예제1) 아래와 같이 출력하시오.

 

/*
	****
	****
	****
	****
*/

 

for(int a=1; a<=4; a=a+1) {
	for(int b=1; b<=4; b=b+1) {
		System.out.print("*");
	}//for end
	System.out.println();
}//for end

 

 

예제2) 구구단 2 ~ 9단을 출력하시오. (반복문 for)

 

for(int dan=2; dan<=9; dan=dan+1) {
	System.out.println(""+dan+"단");
    
	for(int a=1; a<=9; a=a+1) {
		System.out.println(dan+"*"+a+"="+(dan*a));
	}//for end
    
}//for end

/*
	2단
	2*1=2
	2*2=4
	2*3=6
	2*4=8
	2*5=10
	2*6=12
	2*7=14
	2*8=16
	2*9=18

	(생략)
*/

 

 

예제3) 회전수 증가

 

for(int a=1; a<=4; a=a+1) {
	for(int b=1; b<=a; b=b+1) {
		System.out.print("@");
	}//for end
	System.out.println();
}//for end

/*
	@
	@@
	@@@
	@@@@
*/

 

 

예제4) 회전수 감소

 

int a=0, b=0;
for(a=4; a>=1; a=a-1) {
	for(b=1; b<=a; b=b+1) {
		System.out.print("#");
	}//for end
	System.out.println();
}//for end

//System.out.println(a+b); //2

/*
	####
	###
	##
	#
*/

 

이 코드에서 a+b의 값은 다음과 같은 과정을 거친 후 도출되었다.

 

//System.out.println(a+b); //2

/*
	a=4 4>=1 b=1 1<=4
		 b=2 2<=4
		 b=3 3<=4
		 b=4 4<=4
		 b=5 5<=4 *
	a=3 3>=1 b=1 1<=3
		 b=2 2<=3
		 b=3 3<=3
		 b=4 4<=3 *
	a=2 2>=1 b=1 1<=2
		 b=2 2<=2
		 b=3 3<=2 *
	a=1 1>=1 b=1 1<=1
		 b=2 2<=1 *
	a=0 *
		
*/

 

 

 

continue 반복문으로 계속 실행

continue문은 반복문인 for문, while문, do-while문에서만 사용되는데, 블록 내부에서 continue문이 실행되면 for문의 증감식 또는 while문, do-while문의 조건식으로 이동한다.

 

continue문은 반복문을 종료하지 않고 계속 반복을 수행하며 대개 if문과 같이 사용되는데, 특정 조건을 만족하는 경우에 continue문을 실행해서 그 이후의 문장을 실행하지 않고 다음 반복으로 넘어간다. 

 

for(int a=1; a<10; a=a+1) {
	if(a==5) continue;
	System.out.println(a);
}//for end

/*
	1
	2
	3
	4
	6
	7
	8
	9
*/

 

따라서 위의 코드는 5를 제외하고 1부터 9까지의 숫자가 출력된다.

 

 

 

문제1) 알파벳을 한 줄에 5개씩 출력하시오.

 

int count=0;
for(char ch='A'; ch<='Z'; ch++) {
	count=count+1;
	System.out.print(ch);
	if(count%5==0) {
		System.out.println(); //줄바꿈
	}//if end
}//for end

/*
	ABCDE
	FGHIJ
	KLMNO
	PQRST
	UVWXY
	Z
*/

 

char ch='A'라 선언함은 아스키 코드의 사용을 의미하는데, 이때 나타내는 값은 십진법에서 65에 해당한다.

이 문제는 단순하게 영어를 숫자로 치환하여 for문을 사용하는 문제이다.

 

카운트를 먼저하는 개념이 아직도 좀 어색하다. 

내 수학적 사고는 항상 계산을 마친 후 내가 이 계산을 마쳤으니 이것을 한 회차 마쳤다고 표현하여 카운트 +1을 할 것 같은데, 나와는 조금 다르다. 

아무튼 카운트를 해준 후 값을 프린트하고 if문으로 5회차 단위로 잘라서 줄 바꿈이 들어가면 된다.

 

 

 

문제2) 누적의 합을 구하시오.

 

/* 출력결과
	1+.....+10  =55
	1+.....+20  =210
	1+.....+30  =
			
	1+.....+90  =
	1+.....+100 =5050
*/

 

내 답안

 

int a, b, hap=0;
for(a=10; a<=100; a=a+10) {
	for(b=1; b<=a; b=b+1) {
		hap=hap+b;
						
	}//for end
	System.out.println("1+....+"+a+"="+hap);
	hap=0;
}//for end

/*
	1+....+10=55
	1+....+20=210
	1+....+30=465
	1+....+40=820
	1+....+50=1275
	1+....+60=1830
	1+....+70=2485
	1+....+80=3240
	1+....+90=4095
	1+....+100=5050
*/

 

상대적으로 쉬운 문제인 것 같다.

a변수의 값을 10, 20, 30, ..., 100으로 두고 b변수를 1부터 a변수 값 사이까지로 설정하면 끝.

 

 

 

문제3) 아래와 같이 출력하시오.

 

/*
	@★★★
	★@★★
	★★@★
	★★★@
*/

 

내 답안

 

int a, b, count=0;
for(a=1; a<=4; a++) {
	
    for(b=1; b<=4; b++) {
    	count=count+1; //의미 모를 count
		
        if(b==a) {
        	System.out.print("@");
        }else {
        	System.out.print("*");
			
            if(count%4==0) { //의미 모를 if문
            	System.out.println();
            }//if end
        }//if end
        
    }//for end
}//for end

 

의미 없는 count 선언과 의미 없는 if문 중첩이다. 

count 선언을 활용하려면 for문을 두 번 돌릴 필요가 없다.

 

int count=0, gol=0;
do {
	if(count%5==0) {
		System.out.print("@");
        
		if(count%4==3) {
			System.out.println();
		}//if end
        
		count++;
		gol++;
				
	}else {
		System.out.print("*");
        
		if(count%4==3) {
			System.out.println();
		}//if end
        
		count++;
        
	}//if end
}while(gol<4);

/*
	@***
	*@**
	**@*
	***@
*/

 

위와 같은 do-while문을 활용할 수 있다.

이 코드는 @이 1번 올 때 ★이 4번 오는 것을 토대로 만들어진 문장이다.

이 코드보다는 for문이 훨씬 쉽다.

 

 

선생님 답안

 

for(int a=1; a<=4; a++) {		
	for(int b=1; b<=4; b++) {			
		if(b==a) {
			System.out.print("@");
		}else {
			System.out.print("*");
		}//if end
	}//for end
	System.out.println();
}//for end

 

 

 

문제4) 2g, 3g, 5g짜리 추가 각각 5개씩 있을 때

         세 가지의 추의 조합으로 무게가 40 ~ 45 g 사이일 때

         각 추의 갯수와 무게를 출력하는 프로그램

 

/*
	출력결과
	2g	3g	5g	total
	1	5	5	42
	2	4	5	41
	2	5	5	44
*/

 

내 답안

 

int a, b, c;
int sum=0, Asum=0, Bsum=0, Csum=0;
		
System.out.println("2g 3g 5g total");
for(a=0; a<=5; a++) {
	Asum=0;
	Asum=Asum+a*2; //2g 추를 사용하는 경우
			
	for(b=0; b<=5; b++) {
		Bsum=0;
		Bsum=Bsum+b*3; //3g 추를 사용하는 경우
				
		for(c=0; c<=5; c++) {
			Csum=0;
			Csum=Csum+c*5; //5g 추를 사용하는 경우
					
			sum=Asum+Bsum+Csum;
			if(sum>=40 && sum<=45) {
				System.out.printf("%d %2d %2d %3d", a, b, c, sum);
				System.out.println();
			}//if end
		}//for end
	}//for end
}//for end

/*
	2g 3g 5g total
	0  5  5  40
	1  5  5  42
	2  4  5  41
	2  5  5  44
	3  3  5  40
	3  4  5  43
	3  5  4  41
	4  3  5  42
	4  4  4  40
	4  4  5  45
	4  5  4  43
	5  2  5  41
	5  3  5  44
	5  4  4  42
	5  5  3  40
	5  5  4  45
*/

 

for문을 중첩으로 3차례 사용하고 마지막 for문에서 if문을 사용하는 for-if 중첩문이다.

2g, 3g, 5g짜리 추를 각각 5개만 사용할 수 있으므로 for문은 각각의 추를 아예 사용하지 않는 경우부터 시작해서 5개를 전부 다 사용하는 경우까지로 범위를 지정할 수 있다. 

2g, 3g, 5g짜리 추마다 for문을 지정한 후 나온 값들의 총합이 40g 이상 45g 이하의 범위 안에 들어오는 경우를 if문으로 받아내 출력한다.

 

 

선생님 답안

 

System.out.println("2g  3g  5g  total");

int total=0;
for(int a=1; a<=5; a=a+1) {
	for(int b=1; b<=5; b=b+1) {
		for(int c=1; c<=5; c=c+1) {
					
			total=(a*2)+(b*3)+(c*5);
            
			if(total>=40 && total<=45) {
				System.out.println(" "+a+"   "+b+"   "+c+"   "+total);
			}//if end
					
		}//for end
	}//for end
}//for end

/*
	2g  3g  5g  total
	 1   5   5   42
	 2   4   5   41
	 2   5   5   44
	 3   3   5   40
	 3   4   5   43
	 3   5   4   41
	 4   3   5   42
	 4   4   4   40
	 4   4   5   45
	 4   5   4   43
	 5   2   5   41
	 5   3   5   44
	 5   4   4   42
	 5   5   3   40
	 5   5   4   45
*/

 

선생님 답안은 추가 선택되지 않는 경우를 고려하지 않았다는 것이다.

내 답안은 2g짜리 추가 선택되지 않고 나머지 추들이 5개씩 선택되는 경우도 포함된다.

 

 

 

배열 Array

하나의 변수에 1개 이상의 동일한 자료형의 값을 저장할 수 있는 공간

만약 다른 자료형의 값을 저장하려고 하면 타입 불일치(Type mismatch) 컴파일 오류가 발생한다.

 

그리고 한 번 생성된 배열은 길이를 늘리거나 줄일 수 없다. 

 

element 요소

index 순서, 색인

 

1차원 배열 : [열]

2차원 배열 : [행][열]

3차원 배열 : (자바에는 없는 문법)

 

열, 칸, column

행, 줄, row

 

new 연산자 : 메모리 할당(확보) 연산자

 

 

1차원 배열 선언

다음 코드는 4바이트 단위의 int 자료형을 3개의 값으로 저장하는 배열을 생성한 것이다.

→ 총12바이트 메모리를 확보

 

int[] kor=new int[3];
kor[0]=10;
kor[1]=20;
kor[2]=30;

System.out.println(kor[0]); //10
System.out.println(kor[1]); //20
System.out.println(kor[2]); //30

 

 

배열 요소의 갯수

. 을 기준으로 패키지를 구분할 수 있다.

 

System.out.println(kor.length); //3

 

 

메모리 할당 및 초기값 저장

 

int[] eng= {40, 50, 60}; //new 3칸
for(int i=0; i<eng.length; i++) {
	System.out.println(eng[i]);
}//for end

/*
	40
	50
	60
*/

 

 

ArrayIndexOutOfBoundsException 발생

인덱스의 범위를 벗어나는 경우 나타나는 결과값이다.

 

System.out.println(eng[3]); //에러

 

위의 코드를 출력하면 다음과 같은 결과값이 나온다.

 

 

 

예제1) 실수형에 대한 배열

 

double[] aver= {1.2, 3.4, 5.6};
for(int i=0; i<aver.length; i++) {
	System.out.println(aver[i]);
}//for end

/*
	1.2
	3.4
	5.6
*/

 

 

예제2) 문자형에 대한 배열

 

char[] ch= {'H', 'E', 'L', 'L', 'O'}; //문자형 기호 주의 ' '
for(int i=0; i<ch.length; i++) {
	System.out.println(ch[i]);
}//for end

/*
	H
	E
	L
	L
	O
*/

 

 

예제3) 문자열형에 대한 배열

 

String[] name= {"진달래", "개나리", "무궁화"};
for(int i=0; i<name.length; i++) {
	System.out.println(name[i]);
}//for end	

/*
	진달래
	개나리
	무궁화
*/

 

 

문제) 배열 요소의 전체 합을 구하시오.

 

int[] num= {3, 5, 7};

int hap=num[0]+num[1]+num[2];
System.out.println(hap); //15

 

또는

 

int hap=0;
for(int i=0; i<num.length; i++) {
	hap=hap+num[i];
}//for end
System.out.println(hap); //15

 

 

 

문제1) 요일 구하는 프로그램

다음과 같은 방식으로 풀이하면 된다.

 

/*
	서기 1년 1월 1일 ~ 2020년 8월 20일= 총날수
	총날수%7 => 0일 1월 2화 3수 4목 5금 6토
		1.1.1 ~ 1.1.1
		1%7
		1월
				
	1)단계 -> 서기1년~서기2019년
		윤년+=366
		평년+=365
			
	2)단계 -> 1월 ~ 7월
		1 3 5 7 8 10 12 +=31
		4 6 9 11        +=30
		2               +=29 (윤년)
		2               +=28 (평년)
			
	3)단계
		+=20
			
*/	

 

1) 전체 일수

 

int cYear=2020, cMonth=8, cDate=20;

int hap=0; //전체 일수
for(int y=1; y<cYear; y++) {
	if(y%4==0 && y%100!=0 || y%400==0) {
		hap=hap+366;
	}else {
		hap=hap+365;
	}//if end			
}//for end
System.out.println(hap); //737424

 

2) 윤년, 평년에 따른 매달의 일수 계산

 

내 답안

 

int cYear=2020, cMonth=8, cDate=20;

//내 답 -> 2020년의 윤달을 먼저 구하고 해당 식을 뒤에 나열한 배열에 편입시키는 방식으로 진행함

int[] Month= new int [13];
if(cYear%4==0 && cYear%100!=0 || cYear%400==0) {
	Month[2]=29;
}else {
	Month[2]=28;
}//if end
System.out.println(Month[2]); //29(윤달)

Month[0]=0;
Month[1]=31;
Month[3]=31;
Month[5]=31;
Month[7]=31;
Month[8]=31;
Month[10]=31;
Month[12]=31;
Month[4]=30;
Month[6]=30;
Month[9]=30;
Month[11]=30;

for(int mon=0; mon<cMonth; mon++) {
	hap=hap+Month[mon]; //mon=0; 1월 ~ mon<cMonth(8월); 7월
}//for end
System.out.println(hap); //737637

 

선생님 답안

 

int cYear=2020, cMonth=8, cDate=20;

int[] mon= {0,31,28,31,30,31,30,31,31,30,31,30,31};	
//2월을 28일로 먼저 두고 2020년의 윤달 여부를 계산
		
if(cYear%4==0 && cYear%100!=0 || cYear%400==0) {
	mon[2]=29;	//mon[2]=29가 맞는 경우 mon[2]=28 위치에 대입
				//아닌 경우 mon[2]=28 유지
}//if end
		
for(int m=1; m<cMonth; m++) {
	hap=hap+mon[m];
}//for end
		

 

선생님 방식이 더 편하다. 윤달에 대한 값을 대입 후 그것이 맞는지 틀린지를 확인하는 방법

내 답안에서 변수 별로 대입한 것은 한 번 해보고 싶었다.

 

3) 요일 도출

 

hap=hap+cDate;
System.out.println(hap);		//737657
		
System.out.println("총날수:"+hap);//총날수:737657
		
switch(hap%7) {
case 0: System.out.println("일요일"); break;
case 1: System.out.println("월요일"); break;
case 2: System.out.println("화요일"); break;
case 3: System.out.println("수요일"); break;
case 4: System.out.println("목요일"); break;
case 5: System.out.println("금요일"); break;
case 6: System.out.println("토요일"); break;
}//switch end
		
//목요일

 

단순한 스위치문이다. 구해진 전체 일수를 7로 나눈 나머지값에 따라 결과값이 달라진다.