[Do it! 알고리즘]01. 기본 알고리즘
01-1 알고리즘이란?
알고리즘이란? 문제를 해결하기 위한 것으로, 명확하게 정의되고 순서가 있는 유한 개의 규칙으로 이루어진 집합
- 아무리 명확하게 알고리즘을 정의해도 변수의 값에 따라 결과가 맞기도 하고 틀리기도 한다면 올바른 알고리즘이라 할 수 없다.
(1) 세 값의 최댓값
세 값의 최댓값 구하기
- 3개의 정수 가운데 ‘최댓값’을 구하는 프로그램을 작성한다. 변수
a,b,c에 들어가는 값은 키보드에서 입력한 값이고, 그 3개의 값 중 최댓값을 변수max로 찾는다.
package chapter01;
import java.util.Scanner;
public class ex01 {
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
System.out.println("세 정수 중 최댓값 구하기");
System.out.print("a의 값 : ");
int a = stdIn.nextInt();
System.out.print("b의 값 : ");
int b = stdIn.nextInt();
System.out.print("c의 값 : ");
int c = stdIn.nextInt();
int max = a;
if (b > max) {
max = b;
}
if (c > max) {
max = c;
}
System.out.printf("최댓값 : %s \n", max);
}
}
System.in: 키보드와 연결된 표준 입력 스트림(standard input stream)stdIn: 키보드와 연결된 표준 입력 스트림(System.in)에서 문자나 숫자를 꺼내는 장치 역할- 실행 결과
세 정수 중 최댓값 구하기
a의 값 : 10
b의 값 : 20
c의 값 : 30
최댓값 : 30
- 변수
a,b,c의 최댓값을max로 구하는 과정max에a값을 넣는다.b값이max보다 크면max에b값을 넣는다c값이max보다 크면max에c값을 넣는다.
순차적 구조 & 선택 구조
- 세 문장이 아래로 나란히 있다면 이 문장은 순서대로 실행된다. 이렇게 여러 문장(프로세스)이 순차적으로 실행되는 구조를 순차적(concatenation) 구조라고 한다.
()안에 있는 식의 평가 결과에 따라 프로그램의 실행 흐름을 변경하는if문을 선택(selection) 구조라고 한다.
여러 값의 최댓값 구하기
- 최댓값을 여러 번 반복해서 구하는 경우에는 메서드로 처리하면 편리하다.
package chapter01;
public class ex02 {
// 3개의 정수 중 최댓값을 구한다.
static int findMax(int a, int b, int c) {
int max = a;
if (b > max) max = b;
if (c > max) max = c;
return max;
}
public static void main(String[] args) {
System.out.println("max3(3,2,1) = " + findMax(3,2,1));
System.out.println("max3(3,2,2) = " + findMax(3,2,2));
System.out.println("max3(3,1,2) = " + findMax(3,1,2));
System.out.println("max3(3,2,3) = " + findMax(3,2,3));
System.out.println("max3(2,1,3) = " + findMax(2,1,3));
System.out.println("max3(3,3,2) = " + findMax(3,3,2));
System.out.println("max3(3,3,3) = " + findMax(3,3,3));
System.out.println("max3(2,2,3) = " + findMax(2,2,3));
System.out.println("max3(2,3,1) = " + findMax(2,3,1));
System.out.println("max3(2,3,2) = " + findMax(2,3,2));
System.out.println("max3(1,3,2) = " + findMax(1,3,2));
System.out.println("max3(2,3,3) = " + findMax(2,3,3));
System.out.println("max3(1,2,3) = " + findMax(1,2,3));
}
}
- 실행 결과, 모든 조합에 대해 모두 3이 출력되어 최댓값이 바르게 구해진 것을 확인할 수 있다.
max3(3,2,1) = 3
max3(3,2,2) = 3
max3(3,1,2) = 3
max3(3,2,3) = 3
max3(2,1,3) = 3
max3(3,3,2) = 3
max3(3,3,3) = 3
max3(2,2,3) = 3
max3(2,3,1) = 3
max3(2,3,2) = 3
max3(1,3,2) = 3
max3(2,3,3) = 3
max3(1,2,3) = 3
매개변수
- 메서드를 정의할 때 메서드에 전달되는 값을 저장하기 위해 변수(variable)을 선언하는데, 이를 매개변수(parameter) 또는 형식적 매개변수(formal parameter)라 한다.
- 형식매개변수를 가인수라 하고 메서드를 호출할 때 사용하는 매개변수 값(value)을 실인수(actual argument)라고 한다.
연습문제
- Q1) 네 값의 최댓값을 구하는 메서드를 작성하세요.
static int findMax(int a, int b, int c, int d) {
int max = a;
if (b > max) max = b;
if (c > max) max = c;
if (d > max) max = d;
return max;
}
- Q2) 세 값의 최솟값을 구하는 메서드를 작성하세요.
static int findMin(int a, int b, int c) {
int min = a;
if (b < min) min = b;
if (c < min) min = c;
return min;
}
- Q3) 네 값의 최솟값을 구하는 메서드를 작성하세요.
static int findMin(int a, int b, int c, int d) {
int min = a;
if (b < min) min = b;
if (c < min) min = c;
if (d < min) max = d;
return min;
}
세 값의 중앙값
- 세 정수의 중앙값을 구하는
findMed메서드를 정의한다.
package chapter01;
import java.util.Scanner;
public class ex03 {
static int findMed(int a, int b, int c) {
if (a >= b) {
if (b >= c) {
return b;
} else if (a <= c) {
return a;
} else {
return c;
}
} else if (a > c) {
return a;
} else if (b > c) {
return c;
} else {
return b;
}
}
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
System.out.println("세 정수의 중앙값 구하기");
System.out.print("a의 값 : ");
int a = stdIn.nextInt();
System.out.print("b의 값 : ");
int b = stdIn.nextInt();
System.out.print("c의 값 : ");
int c = stdIn.nextInt();
System.out.println("중앙값 : " +findMed(a, b, c));
}
}
연습문제
- Q4) 세 값의 대소 관계 13종류의 모든 조합에 대해 중앙값을 구하여 출력하는 프로그램을 작성하세요.
package chapter01;
import java.util.Scanner;
public class quiz04 {
static int findMed(int a, int b, int c) {
if (a >= b) {
if (b >= c) {
return b;
} else if (a <= c) {
return a;
} else {
return c;
}
} else if (a > c) {
return a;
} else if (b > c) {
return c;
} else {
return b;
}
}
public static void main(String[] args) {
System.out.println("median3(3,2,1) =" + findMed(3, 2, 1));
System.out.println("median3(3,2,2) =" + findMed(3, 2, 2));
System.out.println("median3(3,1,2) =" + findMed(3, 1, 2));
System.out.println("median3(3,2,3) =" + findMed(3, 2, 3));
System.out.println("median3(2,1,3) =" + findMed(2, 1, 3));
System.out.println("median3(3,3,2) =" + findMed(3, 3, 2));
System.out.println("median3(3,3,3) =" + findMed(3, 3, 3));
System.out.println("median3(2,2,3) =" + findMed(2, 2, 3));
System.out.println("median3(2,3,1) =" + findMed(2, 3, 1));
System.out.println("median3(2,3,2) =" + findMed(2, 3, 2));
System.out.println("median3(1,3,2) =" + findMed(1, 3, 2));
System.out.println("median3(2,3,3) =" + findMed(2, 3, 3));
System.out.println("median3(1,2,3) =" + findMed(1, 2, 3));
}
}
- Q5) 중앙값을 구하는 메서드는 다음과 같이 작성할 수도 있다. 그러나 기존에 작성했던
findMed메서드에 비해 효율이 떨어지는데, 그 이유를 설명하세요.
static int findMed2(int a, int b, int c) {
if ((b >= a && c <= a) || (b <= a && c >= a))
return a;
else if ((a > b && c < b) || (a < b && c > b))
return b;
return c;
}
위의 findMed2 메서드의 경우, 중앙값을 구하기 위해 같은 연산을 중복해서 수행하기도 하고 기존 메서드보다 더 많은 연산을 수행해야 한다.
// 가장 처음의 if문의 판단
// if ((b >= a && c<= a) || (b <= a && c >= a))
// 에 주목합니다.
// 여기서 b >= a 및 b <= a의 판단을 뒤집은 판단(실질적으로 같은 판단)을 이어지는 else 이후의
// else if ((a > b && c < b) || (b <= a && c > b))
// 으로 수행합니다.
// 결국 가장 처음의 if가 성립한 경우 2 번째의 if에서도 (실질적으로)같은 판단을 수행하므로 효율이 나빠집니다.
(2) 조건 판단과 분기
if - else if - else
- 변수
no의 값이 양수인지, 음수인지, 0인지에 따라 한 가지가 실행된다. 두 가지가 동시에 실행되거나 하나도 실행되지 않거나 하는 경우는 없다. 이는 프로그램의 흐름이 세 가지로 분기하기 때문이다.
package chapter01;
import java.util.Scanner;
public class ex04 {
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
System.out.println("정수를 입력하세요 : ");
int no = stdIn.nextInt();
if (no > 0)
System.out.println("입력한 숫자는 양수입니다.");
else if (no < 0)
System.out.println("입력한 숫자는 음수입니다.");
else
System.out.println("입력한 숫자는 0입니다.");
}
}
if - else if - else if
- 프로그램의 흐름은 실제로 네 가지로 분기한다.
if (no == 1)
System.out.println("입력한 숫자는 1입니다.");
else if (no == 2)
System.out.println("입력한 숫자는 2입니다.");
else if (no == 3)
System.out.println("입력한 숫자는 3입니다.");
// if - else if - else (프로그램의 흐름이 세 가지로 분기)
// 입력한 값이 1과 2가 아니면 "입력한 숫자는 3입니다."가 출력된다.
if (no == 1)
System.out.println("입력한 숫자는 1입니다.");
else if (no == 2)
System.out.println("입력한 숫자는 2입니다.");
else
System.out.println("입력한 숫자는 3입니다.");
- 실제로는 마지막에 공백문이 실행된다.
if (no == 1)
System.out.println("입력한 숫자는 1입니다.");
else if (no == 2)
System.out.println("입력한 숫자는 2입니다.");
else if (no == 3)
System.out.println("입력한 숫자는 3입니다.");
else
; // 공백문 (실제로 아무것도 하지 않는 문장)
연산자와 피연산자
- 연산자(operator) :
+,-등의 기호 - 피연산자(operand) : 연산의 대상이 되는 것
- 연산자는 피연산자의 수에 따라 3종류로 분류된다.
- 단항 연산자 : 피연산자 1개. 예)
a++ - 2항 연산자 : 피연산자 2개. 예)
a < b - 3항 연산자 : 피연산자 3개. 예)
a ? b : c
- 단항 연산자 : 피연산자 1개. 예)
- 조건 연산자(conditional operator)
? :는 자바에서 유일한 2항 연산자이다.a ? b : c는a가true이면b를 반환하고,false이면c를 반환한다.
(3) 순서도의 기호
- 데이터(data) : 데이터의 입력과 출력을 나타낸다.
- 처리(process) : 여러 종류의 처리 기능을 수행한다. 즉, 정보의 값, 자료형, 위치를 바꾸도록 정의한 연산이나 연산집합의 실행 도는 연속적인 몇 가지 흐름 가운데 하나의 방향을 결정하는 연산집합이나 연산군의 실행을 나타낸다.
- 미리 정의한 처리(predefined process) : 서브 루틴 및 모듈 등 다른 곳에서 이미 정의한 하나 이상의 연산 도는 명령어들로 이루어진 처리를 나타낸다.
- 판단(decision) : 하나의 입구와 하나 이상을 선택할 수 있는 출구가 있고, 기호에서 정의한 조건을 평가하여 하나의 출구를 선택하는 판단 기능(스위치형 기능)을 나타낸다. 주로 예상되는 평가 결과의 경로를 선 가까이에 쓴다.
- 루프 범위(loop limit) : 두 부분으로 구성되어 루프트 시작과 종료를 나타낸다. 기호의 두 부분에는 같은 이름(루프에 대한 임의의 이름)을 사용한다.
- 선(line) : 제어의 흐름을 나타낸다. 흐름의 방향을 분명히 나타내고자 할 때 화살표를 붙인다. 선은 위에서 아래로 내려가는 것이 원칙이다.
- 단말(terminator) : 외부 환경으로 나가거나 외부 환경에서 들어오는 것을 나타낸다. 예를 들어 프로그램 흐름의 시작과 종료를 나타낸다.
01-2 반복
(1) 1부터 n까지의 정수 합 구하기
- 사용자에게 하나의 정수를 입력받아 1부터 그 정수까지의 합을 구하는 프로그램을 작성한다.
package chapter01;
import java.util.Scanner;
public class ex05 {
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
System.out.println("1부터 n까지의 합 구하기");
System.out.print("n의 값 : ");
int n = stdIn.nextInt();
int sum = 0;
int i = 1;
// 변수 i의 값이 n 이하인 동안
// i의 값을 1씩 증가하면서 루프 본문을 n회 반복 실행
while (i <= n) {
sum += i;
i++; // 최종 i의 값은 n이 아니라 n+1이다.
}
System.out.printf("1부터 %d까지의 합 : %d", n, sum);
}
}
- 실행 결과
1부터 n까지의 합 구하기
n의 값 : 10
1부터 10까지의 합 : 55
while문 반복
- 어떤 조건이 성립하는 동안 처리를 방복하여 실행하는 것을 반복(repetition) 구조라 하며 일반적으로 루프(loop)라고 부른다.
while문은 실행전에 반복을 계속할지를 판단하는데, 이를 ‘사전 판단 반복 구조‘라고 부른다. 제어식의 평갓값이0이 아니면 프로그램 명령문이 반복된다. 반복의 대상이 되는 ‘명령문’을 문법적으로는 루프 본문이라 한다.
while(제어식) 명령문
for문 반복
- 하나의 변수를 사용하는 반복문은
for문을 사용하는 것이 좋다. - 초기화 부분은
for문을 실행학기 전에 한 번만 실행한다. 제어식을 평가한 값이true이면for문의 명령문을 반복한다. 명령문을 실행한 다음에는 업데이트 부분을 실행한다.
for(초기화 부분; 제어식; 업데이트 부분) 명령문
1부터n까지의 정수의 합을for문으로 구하는 프로그램을 작성한다.
package chapter01;
import java.util.Scanner;
public class ex06 {
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
System.out.println("1부터 n까지의 합 구하기");
System.out.print("n의 값 : ");
int n = stdIn.nextInt();
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += i;
}
System.out.printf("1부터 %d까지의 합 : %d", n, sum);
}
}
- 실행 결과
1부터 n까지의 합 구하기
n의 값 : 10
1부터 10까지의 합 : 55
for문 자세히 알아보기
for문의 초기화 부분, 제어식, 업데이트 부분은 생략이 가능하다. 세 부분 모두 생략이 가능하지만 세미콜론(;)은 생략하면 안된다.for문의 초기화 부분에서 선언한 변수는for문 안에서만 유효하다. 따라서for문을 종료한 다음에도 변수를 사용하려면for문 바깥 부분에서 변수를 선언해야 한다.
int i;
for (int 1; i <= n; i++) {
sum += i;
}
- 같은 함수의 하나 이상의
for문에서 같은 이름의 변수를 사용하려면 각for문마다 변수를 선언하면 된다.
for (int i = 1; i <= 3; i++) {
sum += i;
}
for (int i = 1; i <= 5; i++) {
System.out.println(i);
}
연습문제
- Q6)
ex05의while문이 종료될 때 변수i의 값이n+1이 됨을 확인하세요(변수 i값을 출력하도록 프로그램을 수정하세요)
package chapter01;
import java.util.Scanner;
public class quiz06 {
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
System.out.println("1부터 n까지의 합 구하기");
System.out.print("n의 값 : ");
int n = stdIn.nextInt();
int sum = 0;
int i = 1;
while (i <= n) {
sum += i;
i++;
}
System.out.println("i = " + i);
System.out.printf("1부터 %d까지의 합 : %d", n, sum);
}
}
- Q7)
n이7이면'1 + 2 + 3 + 4+ 5+ 6+ 7 = 28'로 출력하는 프로그램을 작성하세요.
package chapter01;
import java.util.Scanner;
public class quie07 {
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
System.out.println("1부터 n까지의 합 구하기");
System.out.print("n의 값 : ");
int n = stdIn.nextInt();
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += i;
if (i < n) {
System.out.print(i + " + ");
} else {
System.out.print(i + " = ");
}
}
System.out.print(sum);
}
}
- Q8)
1부터10까지의 합은(1+10)*5와 같은 방법으로 구할 수 있습니다. 가우스의 덧셈이라는 방법을 이용하여1부터n까지의 정수 합을 구하는 프로그램을 작성하세요.
package chapter01;
import java.util.Scanner;
public class quiz08 {
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
System.out.println("1부터 n까지의 합 구하기");
System.out.print("n의 값 : ");
int n = stdIn.nextInt();
int sum = (n + 1) * (n / 2) + (n % 2 == 1 ? (n + 1) / 2 : 0);
System.out.printf("1부터 %d까지의 합 : %d", n, sum);
}
}
- Q9) 정수
a,b를 포함하여 그 사이의 모든 정수의 합을 구하여 반환하는 메서드를 작성하세요.
// 나의 풀이
static int sumof(int a, int b) {
int sum = 0;
if (a >= b) {
for (int i = b; i <= a; i++) {
sum += i;
}
} else {
for (int i = a; i <= b; i++) {
sum += i;
}
}
return sum;
}
// 해설
static int sumof(int a, int b) {
int min; // a, b의 작은 쪽의 값
int max; // a, b의 큰 쪽의 값
if (a < b) {
min = a;
max = b;
} else {
min = b;
max = a;
}
int sum = 0; // 합
for (int i = min; i <= max; i++)
sum += i;
return (sum);
}
(2) 양수만 입력하기
1부터n까지의 정수의 합을 구하는 프로그램을 작성하되, 사용자가n의 값으로0이하의 값을 입력하면 다시'n의 값 : '이라고 출력되며 사용자에게 다시 입력할 것을 요구하도록 한다.
package chapter01;
import java.util.Scanner;
public class ex06 {
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
int n;
System.out.println("1부터 n까지의 합 구하기");
// n이 0보다 클 때까지 반복
do {
System.out.print("n의 값 : ");
n = stdIn.nextInt();
} while (n <= 0);
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += i;
}
System.out.printf("1부터 %d까지의 합 : %d", n, sum);
}
}
- 실행 결과
1부터 n까지의 합 구하기
n의 값 : -5
n의 값 : 0
n의 값 : 10
1부터 10까지의 합 : 55
do문
do문은 일단 루프 본문을 한 번 실행한 다음에 계속 반복할 것인지를 판단하는 사후 판단 반복문이다.while문과 마찬가지로()안의 제어식을 평가한 값이0이 아니면 루프 본문의 명령문이 반복된다.
do문 while(제어식);
- 위의 코드에서는 양수만 입력 받기 위해
do문으로 프로그램을 작성했다. 변수n에 입력한 값이0이하면 루프 본문이 반복 실행된다. 그러므로do문이 종료될 때n의 값은 반드시 양수여야 한다.
사전 판단 반복과 사후 판단 반복의 차이점
- 사전 판단 반복문인
while문과for문은 처음에 제어식을 평가한 결과가0이면 루프 본문은 한 번도 실행되지 않는다. - 사후 판단 반복문인
do문은 루프 본문이 반드시 한 번은 실행된다.
연습 문제
- Q10) 오른쪽과 같이 두 변수
a,b에 정수를 입력하고b - a를 출력하는 프로그램을 작성하세요. 단, 변수b에 입력한 값이a이하면변 변수b의 값을 다시 입력하세요.
package chapter01;
import java.util.Scanner;
// 나의 풀이
public class quiz10 {
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
int a, b;
System.out.print("a의 값 : ");
a = stdIn.nextInt();
do {
System.out.print("b의 값 : ");
b = stdIn.nextInt();
} while (b <= a);
System.out.printf("b - a는 %d입니다.", b - a);
}
}
// 해설
class Difference_01_10 {
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
System.out.print("a의 값:");
int a = stdIn.nextInt();
int b=0;
while (true) {
System.out.print("b의 값:");
b = stdIn.nextInt();
if (b > a)
break;
System.out.println("a보다 큰 값을 입력하세요!");
}
System.out.println("b - a는 " + (b - a) + "입니다.");
}
}
- Q11) 양의 정수를 입력하고 자릿수를 출력하는 프로그램을 작성하세요. 예를 들어
135를 입력하면 ‘그 수는 3자리입니다.’라고 출력하고,1314를 입력하면 ‘그 수는 4자리입니다.’라고 출력하면 됩니다.
package chapter01;
import java.util.Scanner;
public class quiz11 {
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
int n;
do {
System.out.print("양의 정수를 입력하세요 > ");
n = stdIn.nextInt();
} while (n <= 0);
int result = 0;
while (n > 0) {
n /= 10;
result++;
}
System.out.printf("입력한 수는 %d자리수 입니다.", result);
}
}
(3) 구조적 프로그래밍
- 하나의 입구와 하나의 출구를 가진 구성 요소만을 계층적으로 배치하여 프로그램을 구성하는 방법을 구조적 프로그래밍(structured programming)이라고 한다. 구조적 프로그래밍은 순처, 선택, 반복이라는 3종류의 제어 흐름을 사용한다.
- 사용자가 입력할 수 있는 값을 ‘2자리 양수’로 제한하는 프로그램을 작성한다.
package chapter01;
import java.util.Scanner;
public class ex07 {
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
int n;
do {
System.out.print("2자리의 정수를 입력하세요 > ");
n = stdIn.nextInt();
} while (n < 10 || n > 99);
// 입력한 값이 10보다 작거나 99보다 크면 루프 본문을 반복
System.out.printf("입력한 수는 %d 입니다.", n);
}
}
- 실행 결과
2자리의 정수를 입력하세요 > 1
2자리의 정수를 입력하세요 > 100
2자리의 정수를 입력하세요 > 10
입력한 수는 10 입니다.
논리 연산자의 단축 평가
- 논리 연산의 식 전체를 평가한 결과가 왼쪽 피연산자의 평가 결과만으로 정확해지는 경우 오른쪽 피연산자의 평가를 수행하지 않는데, 이를 단축 평가(short circuit evaluation)라고 한다.
||연산자의 왼쪽 피연산자를 평가한 값이true이면 오른쪽 피연산자는 평가하지 않는다.&&연산자의 경우 왼쪽 피연산자를 평가한 값이false이면 오른쪽 피연산자는 평가하지 않는다.- 예)
ex07에서 사용자가 입력한 값이1인 경우n < 10의 평갓값은 true이므로 오른쪽n > 99를 평가하지 않아도 제어식n < 10 || n > 99의 값이 true가 된다.
드모르간 법칙
- ‘각 조건을 부정하고 논리곱을 논리합으로, 논리합을 논리곱으로 바꾸고 다시 전체를 부정하면 원래의 조건과 같다’라는 법칙을 드모르간 법칙(De Morgan’s laws)이라고 한다.
x && y와 !(!x || !yy)는 같다.
x || y와 !(!x && !y)는 같다.
- 예)
ex07에서 사용자가 입력한 수가 2자리 수인지 검사하는 제어식(n < 10 || n > 99)는 반복을 계속하는 ‘계속 조건‘인 반면,!(n >= 10 || n <= 99)는 반복을 종료하는 ‘종료 조건‘의 부정이다.
(4) 다중 루프
- 반복 안에서 다시 반복을 할 수 있다. 반복 루프가 중첩되는 수준에 따라 ‘이중 루프, 삼중 루프’라고 한다.
곱셈표
- 곱셈표를 출력하는 프로그램을 작성한다.
package chapter01;
public class ex08 {
public static void main(String[] args) {
System.out.println("---------- 곱셈표 ----------");
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= 9; j++) {
System.out.printf("%3d", i * j);
}
System.out.println();
}
}
}
- 실행 결과
---------- 곱셈표 ----------
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
- 바깥쪽의
for문(행 루프)은 세로 방향에 대한 반복이다. 변수i의 값을1부터9까지 증가시키며, 각각의 반복은 표의 ‘1행, 2행, … 9행’에 해당한다. - 안쪽의
for문(열 루프)은 각 행의 가로 방향에 대한 반복이다. 각각의 행에서 변수j의 값을1부터9까지 증가시킨다. - 변수
i의 값을1부터9까지 증가시키는 ‘행 루프’는 9회 반복되고, 각각의 반복으로 변수j의 값을1부터9까지 증가시키는’열 루프’가 9회 반복된다. - 열 루프 종료 후 줄바꿈 문자의 출력은
1부터9까지 출력을 완료한 행에서 줄을 바꾸어 다음 행을 출력하기 위해 사용한다. - 이중 루프는 아래와 같이 처리된다.
i가 1일 때 : j를 1→9로 증가시키면서 1 * j를 출력한다. 그리고 줄 바꿈한다.
i가 2일 때 : j를 1→9로 증가시키면서 2 * j를 출력한다. 그리고 줄 바꿈한다.
i가 3일 때 : j를 1→9로 증가시키면서 3 * j를 출력한다. 그리고 줄 바꿈한다.
...
i가 9일 때 : j를 1→9로 증가시키면서 9 * j를 출력한다. 그리고 줄 바꿈한다.
연습 문제
- Q12) 위쪽과 왼쪽에 곱하는 수가 있는 곱셈표를 출력하는 프로그램을 작성하세요. 구분선은 기호(
|), 마이너스 기호(-), 플러스 기호(+)를 사용하세요.
package chapter01;
public class quiz12 {
public static void main(String[] args) {
System.out.print(" |");
for (int i = 1; i <= 9; i++) {
System.out.printf("%3d", i);
}
System.out.println();
System.out.println("--+----------------------------");
for (int i = 1; i <= 9; i++) {
System.out.printf("%2d|", i);
for (int j = 1; j <= 9; j++) {
System.out.printf("%3d", i * j);
}
System.out.println();
}
}
}
- Q13) 곱셈이 아니라 덧셈을 출력하는 프로그램을 작성하세요. Q12와 같이 표의 위쪽과 왼쪽에 더하는 수를 출력하세요.
package chapter01;
public class quiz13 {
public static void main(String[] args) {
System.out.print(" |");
for (int i = 1; i <= 9; i++) {
System.out.printf("%3d", i);
}
System.out.println();
System.out.println("--+----------------------------");
for (int i = 1; i <= 9; i++) {
System.out.printf("%2d|", i);
for (int j = 1; j <= 9; j++) {
System.out.printf("%3d", i + j);
}
System.out.println();
}
}
}
- Q14) 입력한 수를 한 변으로 하는 정사각형을
*기호로 출력하는 프로그램을 작성하세요.
package chapter01;
import java.util.Scanner;
public class quiz14 {
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
System.out.println("정사각형 출력");
System.out.print("단 수 : ");
int n = stdIn.nextInt();
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
(5) 직각 이등변 삼각형 출력
- 이중 루프를 응용하면 기호를 늘어놓아 삼각형이나 사각형 모양으로 출력할 수있다.
- 사용자가 양의 정수를 입력하면 왼쪽 아래가 직각인 이등변 삼각형을 출력하는 프로그램을 작성한다.
package chapter01;
import java.util.Scanner;
public class ex09 {
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
int n;
System.out.println("왼쪽 아래가 직각인 이등변 삼각형 출력");
do {
System.out.print("몇 단 삼각형입니까? ");
n = stdIn.nextInt();
} while(n <= 0);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
- 실행 결과
왼쪽 아래가 직각인 이등변 삼각형 출력
몇 단 삼각형입니까? 5
*
**
***
****
*****
- 바깥쪽
for문(행 루프)은 변수i의 값을1부터n, 즉 5까지 증가시킨다. 이것은 삼각형의 각 행에 대응하는 세로 방향 반복이다. 안쪽for문(열 루프)은 변수i의 값을1부터i까지 증가시키면서 출력한다. - 이중 루프는 아래와 같이 처리된다.
i가 1일 때 : j를 1→1로 증가시키면서 *를 출력한다. 그리고 줄 바꿈한다. (*)
i가 2일 때 : j를 1→2로 증가시키면서 *를 출력한다. 그리고 줄 바꿈한다. (**)
i가 3일 때 : j를 1→3로 증가시키면서 *를 출력한다. 그리고 줄 바꿈한다. (***)
i가 4일 때 : j를 1→4로 증가시키면서 *를 출력한다. 그리고 줄 바꿈한다. (****)
i가 5일 때 : j를 1→5로 증가시키면서 *를 출력한다. 그리고 줄 바꿈한다. (*****)
연습 문제
- Q15) 다양한 이등변 삼각형을 출력하는 부분을 아래와 같은 형식의 메서드로 작성하세요.
static void triangleLB(int n) // 왼쪽 아래가 직각인 이등변 삼각형 출력
static void triangleLU(int n) // 왼쪽 위가 직각인 이등변 삼각형 출력
static void triangleRU(int n) // 오른쪽 위가 직각인 이등변 삼각형 출력
static void triangleRB(int n) // 오른쪽 아래가 직각인 이등변 삼각형 출력
// 왼쪽 아래가 직각인 이등변 삼각형 출력
static void triangleLB(int n) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
System.out.println();
}
}
// 왼쪽 위가 직각인 이등변 삼각형 출력
// 나의 풀이
static void triangleLU(int n) {
for (int i = n; i <= n && i > 0; i--) {
for (int j = 1; j <= i ; j++) {
System.out.print("*");
}
System.out.println();
}
}
// 해설
static void triangleLU(int n) {
for (int i = 1; i <= n; i++) { // i행 (i = 1, 2, … ,n)
for (int j = 1; j <= n - i + 1; j++) // n-i+1개의 '*'를 나타냄
System.out.print('*');
System.out.println();
}
}
// 오른쪽 위가 직각인 이등변 삼각형 출력
static void triangleRU(int n) {
for (int i = 1; i <= n; i++) { // i행 (i = 1, 2, … ,n)
for (int j = 1; j <= i - 1; j++) // i-1개의 ' '를 나타냄
System.out.print(' ');
for (int j = 1; j <= n - i + 1; j++) // n-i+1개의 '*'를 나타냄
System.out.print('*');
System.out.println();
}
}
// 오른쪽 아래가 직각인 이등변 삼각형 출력
// 나의 풀이
static void triangleRB(int n) {
for (int i = 1; i <= n; i++) {
for (int j = n; j > i ; j--) {
System.out.print(" ");
}
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
System.out.println();
}
}
// 해설
static void triangleRB(int n) {
for (int i = 1; i <= n; i++) { // i행 (i = 1, 2, … ,ln)
for (int j = 1; j <= n - i; j++) // n-i개의 ' '를 나타냄
System.out.print(' ');
for (int j = 1; j <= i; j++) // i개의 '*'를 나타냄
System.out.print('*');
System.out.println();
}
}
- Q16) n단의 피라미드를 출력하는 메서드를 작성하는데, i행에는
(i-1)*2+1개의 기호 문자*가 출력되게 하세요.
// 나의 풀이
static void spira(int n) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n - i; j++) {
System.out.print(" ");
}
for (int j = 1; j <= 2 * i - 1; j++) {
System.out.print("*");
}
System.out.println();
}
}
// 해설
static void spira(int n) {
for (int i = 1; i <= n; i++) { // i행 (i = 1, 2, … ,n)
for (int j = 1; j <= n - i + 1; j++) // n-i+1개의 ' '를 나타냄
System.out.print(' ');
for (int j = 1; j <= (i - 1) * 2 + 1; j++) // (i-1)*2+1개의 '*'를 나타냄
System.out.print('*');
System.out.println();
}
}
- Q17) 아래를 향한
n단의 숫자 피라미드를 출력하는 메서드를 작성하는데,i행에 출력하는 숫자는i % 10으로 구하세요.
static void npira(int n) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n - i; j++) {
System.out.print(" ");
}
for (int j = 1; j <= 2 * i - 1; j++) {
System.out.print(i%10);
}
System.out.println();
}
}