1. 이중 for문
(1) 이중 for문
- 반복문 안에 반복문을 넣는다.
- 0123456789를 6번 출력하고 싶다면 다음과 같다.
for(int i=0; i<10; i++) {
System.out.print("0123456789");
}
- System.out.print("0123456789") 함수 대신 for문을
한개 더 가져올 수 있다.
for(int i=0; i<10; i++) {
for(int j=0; j<10; j++) {
System.out.print(j);
}
}
- 주의: 초기식으로 선언된 i,j 같은 변수들의 이름이 겹치거나 잘못 사용되면 에러 발생.
- 바깥쪽 for문의 반복 코드 부분이 새로 시작하게 되면 내부에 선언된 변수와 for문의 초기문도 새로 실행되어 기존 데이터 사라짐.
(2) 지역변수
- 중괄호 블록 안에 선언된 변수
- 즉, for문의 초기화 식은 해당 for문 중괄호 블록 안에서 지역변수로 사용됨.
int l1 = 1;
{
int l2 = 2;
for(int i=1; i<3; i++) {
for(int j=1; j<3; j++) {
}
}
}
- 0123456789: 옆으로 출력되는 것: 엔터x
- 0123456789: 아래로 출력: 엔터o
- 즉, 0123456789엔터가 반복.
- 이중 for문으로 구현한다고 하면 다음과 같다.
for(int i=0; i<10; i++) {
for(int j=0; j<10; j++) {
System.out.print(j);
}
System.out.print("\n");
}
(3) 이중for문 예제
- 복습용도로 사용

System.out.print("1. ");
for(int i=0; i<1; i++) {
System.out.print(1);
for(int j=0; j<22; j++) {
System.out.print("*");
}
System.out.print(1);
}
System.out.println();
System.out.print("2. ");
for(int k=0; k<4; k++) {
for(int i=0; i<5; i++) {
System.out.print("*");
}
for(int j=0; j<1; j++) {
System.out.print("1");
}
}
System.out.println();
System.out.print("3. ");
for(int k=0; k<4; k++) {
for(int i=0; i<1; i++) {
System.out.print(2);
}
for(int j=0; j<5; j++) {
System.out.print("*");
}
}
System.out.println();
System.out.print("4. ");
for(int i=0; i<1; i++) {
System.out.print(21);
for(int j=0; j<21; j++) {
System.out.print("*");
}
System.out.print(1);
}
System.out.println();
System.out.print("5. ");
for(int k=0; k<4; k++) {
for(int i=0; i<1; i++) {
System.out.print(1);
}
for(int j=0; j<4; j++) {
System.out.print("*");
}
System.out.print(2);
}
System.out.println();
System.out.print("6. ");
for(int k=0; k<4; k++) {
for(int i=0; i<4; i++) {
System.out.print(1);
}
for(int j=0; j<4; j++) {
System.out.print("*");
}
System.out.print(2);
}
System.out.println();
System.out.print("7. ");
for(int k=0; k<3; k++) {
for(int i=0; i<4; i++) {
System.out.print(1);
}
for(int j=0; j<4; j++) {
System.out.print("*");
}
for(int m=0; m<4; m++) {
System.out.print(2);
}
}
System.out.println();
System.out.print("8. ");
for(int n=0; n<3; n++) {
for(int i=0; i<4; i++) {
System.out.print(1);
}
for(int j=0; j<4; j++) {
System.out.print(2);
}
for(int k=0; k<4; k++) {
System.out.print(3);
}
for(int m=0; m<4; m++) {
System.out.print(4);
}
}
1. 빨간공 숫자와 파란공 숫자 1:1 매칭하는 프로그램
int redBalls[] = {1,2,3};
int blueBalls[] = {1,2,3};
System.out.println("빨간공과 파란공을 1:1로 짝지어 매칭된 결과:");
for(int redBall : redBalls) {
for(int blueBall : blueBalls) {
System.out.println(redBall + "→" + blueBall);
}
}
}
}
2. 구구단 프로그램 구현(1)
for(int i=1; i<=9; i++) {
for(int j=1; j<=9; j++) {
System.out.print(i + "*" + j + "=" + (i*j)+ "\t");
}
System.out.println();
}
3. 구구단 프로그램 구현(2)
for(int i=1; i<=9; i+=3) {
for(int j=1; j<=9; j++) {
for(int k=i; k<= i + 2 && k<=9; k++) {
System.out.print(k + "*" + j + "=" + (k*j)+ "\t");
}
System.out.println();
}
System.out.println();
}
- 설명 -
1. 바깥쪽 for문
- for(int i=1; i<=9; i+=3): i값을 1부터 시작하여 3씩 증가해서 9까지 반복.
- 즉, i가 1일때 i를 3씩 증가하게 되어 1,4,7의 구구단 출력. i가 4일때 2,5,8, i가 7일때 3,6,9
2. 내부의 첫번째 for문
- for(int j=1; j<=9; j++): j값이 1부터 시작해서 9까지 1씩 증가하여 반복함.
3. 내부의 두번째 for문
- for(int k=i; k<= i+2 && k<=9; k++): k값을 i부터 시작하고 i+2까지 또는 9까지 반복
- 이 루프는 i값에 따라 현재 그룹의 단을 결정함. 예) i가 1이면 1,2,3 반복, i가 4이면 4,5,6을 선택함.
- 이것은 각 그룹 내에서 1부터 9까지의 숫자를 반복하여 해당하는 구구단을 출력.
2. 정렬
- 두 방법은 실무에서 사용하지 않으니 읽고 이해만 하자.
(1) 버블 정렬
- 두 인접한 요소를 비교하며 배열을 반복적으로 훑어가며 큰 값을 뒤로 보내는 방식.
- 이 정렬은 간단하지만 비효율적 정렬 알고리즘으로 큰 배열이나 데이터가 많을경우 성능 저하
1) 이해 및 설명
1. 배열의 인덱스 0과 1에 들어 있는 수를 비교하여
큰수를 배열의 인덱스1쪽으로 교환하여 이동
2. 0이 작으면 교환되지 않는다.
int arr[] = {6,5,1,8,7,4,2,3};
if(arr[0] > arr[1]) {
int temp;
temp = arr[1];
arr[1] = arr[2];
arr[2] = temp;
}
3. 배열의 인덱스 1과 2에 들어 있는 수를 비교하여 큰수를 배열의
인덱스 2쪽으로 교환
if(arr[1] > arr[2]) {
int temp;
temp = arr[1];
arr[1] = arr[2];
arr[2] = temp;
}
4. 이 작업을 배열이 끝날때까지 반복
5. 반복하게 되면 배열안에 가장 큰 수가 맨 마지막 정렬
for(int i=0; i<arr.length-2; i++) {
if(arr[i]>arr[i+1]) {
int temp;
temp = arr[i];
arr[i] = arr[i+1];
arr[i] = temp;
}
}
6. 이 작업을 2번하면 1번째에 가장 큰 수가 맨 마지막 이동
2번째에 그 다음 큰 수가 배열의 뒤에서 2번째 위치로 이동
for(int i=0; i<arr.length-2; i++) {
if(arr[i]>arr[i+1]) {
int temp;
temp = arr[i];
arr[i] = arr[i+1];
arr[i] = temp;
}
}
for(int i=0; i<arr.length-2; i++) {
if(arr[i]>arr[i+1]) {
int temp;
temp = arr[i];
arr[i] = arr[i+1];
arr[i] = temp;
}
}
7. 반복문을 1번돌때마다 1개의 데이터가 배열의 뒤쪽부터 정렬.
배열의 개수만큼 반복하면 모든 데이터가 정렬
for(int j=0; j<arr.length-1; j++) {
for(int i=0; i<arr.length-2; i++) {
if(arr[i] > arr[i+1]) {
int temp;
temp = arr[i];
arr[i] = arr[i+1];
arr[i] = temp;
}
}
}
8. 내림차수 정렬하고 싶다면 작은수를 뒤쪽으로 보내기
int[] arr = {7,5,9,0,3,1,6,2,4,8};
for(int i = 0; i<arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
for(int j=0; j<arr.length-1; j++) {
for(int i=0; i<arr.length-2; i++) {
if(arr[i] < arr[i+1]) {
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
}
2) 또 다른 예시 설명
int[] array = {5,2,9,1,5,6};
for(int i = 0; i<array.length - 1; i++) {
for(int j=0; j<array.length -1 - i; j++) {
if(array[j] > array[j+1]) {
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
for (int num : array) {
System.out.print(num + " ");
}
}
}
(2) 선택 정렬
- 배열에서 최소값을 선택하여 정렬된 부분과 교환하는 방식
1) 이해 및 설명
int[] array = {64,25,12,22,11};
for(int i=0; i<array.length - 1; i++) {
int minIndex = i;
for(int j = 1+i; j<array.length; j++) {
if(array[j] < array[minIndex]) {
minIndex = j;
}
}
int temp = array[minIndex];
array[minIndex] = array[i];
array[i] = temp;
}
for(int num : array) {
System.out.print(num + " ");
}
--------------------------------------------
<코드 설명>
1. 배열의 크기만큼 반복문 실행. 정렬할 부분의 시작위치 나타냄.
2. 현재 인덱스를 최소값 인덱스로 설정. 초기에 정렬할 부분의 첫번째 요소를 설정.
3. 현재 인덱스 다음부터 배열의 끝까지 순회하며 최소값 찾음. 최소값을 찾으면 minIndex 저장
4. 최소값을 찾은 후 인덱스와 최소값 교환
5. 정렬할 부분을 선택하기 위해 반복문 재시작, 이 과정이 정렬될때까지 반복
2) 또 다른 설명

- 배열 안에서 가장 큰 수를 찾고 배열의 마지막위치와 교환한다.

- 첫번째 교환이 이루어지면 정렬되지 않은 부분의 큰 숫자와 마지막 위치의 값과 교환한다.

- 다음 교환도 두번째 교환과 마찬가지로 큰 수를 선택하고 배열의 마지막 위치와 교환해준다.
- 이런식으로 반복해서 교환하여 정렬해준다.
Tip) 3개라면 2개만 정렬되면 하나는 저절로 정렬.
따라서, 배열크기-1만큼 반복하면 배열은 정렬.
<정리>
1. 인덱스 0번에서 7번까지 8개 중에 큰 수를 찾아 배열 인덱스 7에 들어있는 수와 교환함.
2. 인덱스 0번에서 6번까지 7개 중에 큰 수를 찾아 배열 인덱스 6에 들어있는 수와 교환
3. 인덱스 0번에서 5번까지 6개 중에 큰 수를 찾아 배열 인덱스 5에 들어있는 수와 교환함.
4. 인덱스 0번에서 4번까지 5개 중에 큰 수를 찾아 배열 인덱스 4에 들어있는 수와 교환
5. 인덱스 0번에서 3번까지 4개 중에 큰 수를 찾아 배열 인덱스 3에 들어있는 수와 교환함.
6. 인덱스 0번에서 2번까지 3개 중에 큰 수를 찾아 배열 인덱스 2에 들어있는 수와 교환
7. 인덱스 0번에서 1번까지 2개 중에 큰 수를 찾아 배열 인덱스 1에 들어있는 수와 교환
int arr[] = {6,5,1,8,7,4,2,3};
for(int i=arr.length-1; i>0; i--) {
int findIndex = 0;
for(int j=1; j<=i; j++) {
if(arr[findIndex] < arr[j]) {
findIndex = j;
}
}
int temp = arr[findIndex];
arr[findIndex] = arr[i];
arr[i] = temp;
}
System.out.println(Arrays.toString(arr));
(3) 삽입 정렬
- 배열을 정렬된 부분과 정렬되지 않은 부분을 나누고 정렬되지 않은 부분의 원소를 하나씩 정렬된 부분에 삽입하는 방식
- 배열의 첫번째 원소부터 시작해서 각 원소를 이전 원소들과 비교하여 적절한 위치에 삽입
(4) 병합 정렬
- 배열을 반으로 나눈다음, 각 부분을 재귀적으로 정렬하고 병합하여 정렬된 배열을 생성함.
(5) 퀵 정렬
- 피벗을 기준으로 배열을 분할하고 정복.
- 피벗을 선택하고 작은값을 피벗왼쪽, 큰 값을 오른쪽으로 이동
(6) 힙 정렬
- 자료구조를 활용하여 정렬하는 방법
- 먼저 주어진 배열을 힙으로 만들고 루트 노드(최댓값, 최솟값)를 추출하여 배열 뒤쪽 배치
- 나머지 부분을 다시 힙으로 만들고 루트 노드를 추출하는 과정
(7) 기수 정렬
- 자릿수에 따라 정렬하는 방법
- 숫자를 각 자릿수별로 비교하며 정렬. 먼저 일의자릿수부터 시작하고 십의 자릿수, 백의 자릿수 순으로 정렬