6_java - while문과 증감식

jin·2022년 5월 2일
0

while

whlie문이란?

while문은 반복할 횟수는 미리 알 수 없지만 조건은 알 수 있을 때 주로 사용하는 반복문이다
while문의 구조는 다음과 같으며 조건식이 true일 동안 본체 실맹문을 반복적으로 실행한다.

while (조건식) {
  반복 실행문(); //본체
}

조건식은 반복할 본체를 실행하기 전에 항상 평가해야 하며, 반드시 존재해야 한다. 조건식이 true이면 반복문 본체를 실행하고, false이면 다음 while문 다음 실행문을 수행한다.
한빛아카데미 쉽게 배우는 자바 프로그래밍 2판 / 우종정 지음 발췌


수업 내용

증감식 종류

증감식 종류 (아래 4종류전부 같은뜻이다)
미세한 차이가 있는데 추후에 다시 살펴보겠다.
1) i = i + 1;
2) i += 1;
3) i++;
4) ++i;

증감식은 해당 조건만큼 반복할 횟수를 증가하거나 감소시키기 때문에 반복문에서 주로 쓰인다.

while문

[반복문 while]
구조
1) while ==> 키워드
2) (조건식) ==> 조건의 사실여부 판변한다.
3) {기능} ==> 조건이 사실이면 기능실행한다.
단,반복문은 if 와 다르게 기능종료후 다시 while 실행한다.
4) 중요 ==> 반복문은 반드시 종료 조건을 만들어야한다. (무한반복 방지)

// 예) 1~5까지 출력하시오(반복문사용)
int i = 1;
while (i <=5 ) { // 조건식
  System.out.println(i <= 5); // 조건식이 true 값일때 실행 내용들
  System.out.println(i);
  i++;
}

아래 식과 같이 종료 조건이 없을 경우 무한반복된다.
무한 반복일 경우 콘솔창에서 직접 강제종료를 해야하며 이 상태로 프로젝트를 몇번 더 실행하게 되면 컴퓨터가 심각하게 느려지는 현상이 발생된다.
그러므로 반드시 종료시키는 습관을 길러야 한다.

while (true) {
  System.out.println("~~");
}

while문 알고리즘 문제

1. 배수 문제

7의 배수중 150보다 작은수중 가장큰수 출력하시오. (어떤 수의 배수는 그 수에 정수를 곱한 수이다.)
답 : 147

int i = 0;
int temp; 
int max=7; //temp
		
// i가 150까지 1씩 증가해야함 => i <= 150 / i+1
while (i <=150 ) { // 7의 배수일때 마다 temp에 배수값 저장
  if (i%7==0) {
  temp = i;
  // tump값과 max값을 비교해 tump값이 크면 max값에 넣기
    if (max<temp) {
      max = temp;
   }
  }
  i = i+1;
}
// 반복문 바깥에서 출력해야 한번만 출력됨
System.out.println(max);

2. 약수 문제

148의 약수를 전부 출력하시오. (어떤수를 나누어떨어지게하는수를 그수의 약수라고합니다.)

// 1. 148을 저장할 변수 생성
int num = 148;
// 2. 증가값 변수 생성
int i = 1;
//반복문과 탈출조건
while (i<=num) {
  if (num%i==0) {
	System.out.printf("%d ", i);
  }
  //증가값
  i = i+1;
}

3. 가까운 값 문제

[문제] 1 에서 200 사이의 숫자중 다음 조건에 전부 맞는 숫자를 출력.
[조건1] 6의 배수를출력
[조건2] 100에 가장가까운 수를 출력

// 증가값, 제시된 최대 수 변수 생성
int i = 1; // 시작 수이자 증가값
int max = 200; // 최대 수(마지막까지 반복될 수)
int multiple = 6;
int comparison = 50;
int front = 0; //  100과 비교할 첫번째 값 
int back = 0; // 100과 비교할 두번째 값
while (i <= max) {
  // i는 6의 배수이면서(and) 100보다 작아야함 
  if (i % multiple == 0 && i<=comparison) { 
  //첫번째 100과 가까운 수
  front = i; //마지막 i의 값
  }
 i = i + 1;
}
//두번째 100과 가까운 수 
back = front+multiple;
if (comparison - front < back - comparison) {
  System.out.println("가까운 수" + front);
} else if (comparison - front > back - comparison) {
  System.out.println("가까운 수 " +back);
} else {
  System.out.println("가운데 값 " + front + " " + back);
}

3. 미지수 값 구하기1

[문제] 선호네 반 학생 25명이 체험학습을 하러 가기위해 버스를 탔는데,
총요금이 19400원이였다.
교통카드를 사용하면 720원이고 / 현금으로 지불하면 1000원이다.
이때 교통카드를 사용한 학생수와 현금을 사용한 학생수는 각각 얼마인가?

// 미지수 2개 연립 방정식
// 제시된 조건 / 총 학생수 25, 총 요금 19400
int allStudent = 25;
int allPay = 19400;
		
// 카드와 현금 지불 금액
int card = 720;
int cash = 1000;
		
// 알고 싶은 것 - 카드 사용 학생수와 현금 사용 학생 수
//int cardStudent = 0;
int cardStudent = allStudent;
int cashStudent = 0;
// 반복 돌려서 합이 맞을때까지
// => (카드 요금 * 카드 학생수 ) + (현금 요금 * 현금 학생수 ) = 총요금 
// 			&& 카드학생수 + 현금학생수 = 총 학생 수 
// => 컴퓨터가 계산해주니 증감값 하나는 전체에서 하나씩 빼기 / 하나는 0에서 더하면서 올라가기
		
//탈출 조건 변수 생성
int i = 0;
while (i == 0 ) {
	if (((card * cardStudent) + (cash * cashStudent) == allPay) && (cardStudent + cashStudent == allStudent) ) {
		System.out.println("카드 이용 학생 수 : " + cardStudent + "\n현금 이용 학생 수 : " +cashStudent);
		i = 1;
	}
	cardStudent = cardStudent -1;
	cashStudent = cashStudent +1;
}

4. 각 자리수의 합

[문제] 1~999 사이의 랜덤숫자를 저장하고 각 자리수의 합을 출력하시오.
예) 8 ==> 8
예) 28 ==> 2 + 8
예) 999 ==> 9 + 9 + 9

Random rnd = new Random();
int rNum = rnd.nextInt(999)+1;
int temp = rNum; 
		
// 각 자리 수, 랜덤숫자 자리수 저장할 변수
int one=0, ten=0, hundred=0;
int count = 1;
int cut;
		
int run = 0;
		
System.out.println("반복 안돌린 숫자 : " + temp);
while (run == 0) {
  cut = temp%10;
  System.out.print("반복 회당 cut "+cut+" ");
  if (count == 1) {
  // 일의 자리
  one = cut;
  } else if (count == 2) {
	//십의 자리
	ten = cut;
  } else if (count == 3) {
	// 백의 자리
	hundred = cut;
  }
			
  if (temp/10==0) { //나머지가 없을때까지
	run = 1;
   }
  temp = temp/10; // 반복해서 몫 나누기 => / 사용 
  count = count+1; // 자리수 구하기
  System.out.println(" / 반복 회당 temp : " + temp);
}
System.out.println();
System.out.println("랜덤 숫자 : " + rNum);
System.out.println("백의 자리 : " + hundred + " / 십의 자리 : " + ten + " / 일의 자리 : " + one);
System.out.println("각 자리들의 합 : " + (hundred + ten + one));

5. 요금제 문제

[문제] 아래와같은 휴대요금제가 있다
A요금제 기본요금 17500원 초당 5원 / B요금제 기본요금 31000원 초당 2원
B를 선택할경우 A보다 더 경제적이될려면,통화시간을 얼마까지 사용해야될까요?
정답을 초로 구하시오.

// a요금제에 대한 값
int payA = 17500;
int secA = 5;
// b요금제에 대한 값
int payB = 31000;
int secB = 2;
// 사용량이 얼마나 되어야 금액이 같아지는가? 
// -> 문제 의도는 이상이었으므로 사용량이 크거나 같으면 멈추면 됨 
		
//증가값 use, while 조건문 run
int use = 0, run = 0;
// 언제일때 멈추는가 -> 비싼 기존 요금제+사용량*초당값 >= 비싼 요금제 기존 요금제+사용량*초당값
// -> a요금제 + 사용량 * a요금제 초당 값 >= b요금제 + 사용량 * b요금제 초당 값
while (run == 0) {
  use += 1;
  System.out.println(use* secA + " / " + use* secB);
  if ( payA + (use* secA) >=  payB + (use* secB) ) { //등호 잘못주면?  -> 등호가 반대면 비싼 요금제가 바로 해당되어 바로 true값이 됨
	System.out.println(use);
    run = 1;
  }
}
//위의 문제는 기본 사용량이 제공되지 않는 조건이기 때문에 기본 사용량에 증가되는 초당 사용량값을 계산하여 언제가 효율적인지 구함

덧. while문을 1주동안 붙잡고 있어서 갱신을 못했다.
while문의 작동 매커니즘은 이해됐는데 알고리즘 같은 산술적인 부분이 부족해서 머리를 싸매고 정 해답이 안나오면 질문하고 다시 풀어보는 식으로 5일간 진행했다.
다음 챕터가 단일 for문인데 비슷하니 while보다 수월하지 않을까 싶기도 하고 해보면 알겠지.
덧덧. 마침내 책을 받았다. 인용하는데 전보다 수월하게 찾아서 할 수 있을듯. 시간 남을때 예전 포스팅도 인용하자

0개의 댓글