쭈쌤
쭈쌤 Hello World

[R] 프로그램 흐름제어(3)-기본 문법 활용하기

크리에이티브 커먼즈 라이선스 ITPAPER(호쌤,쭈쌤)에 의해 작성된 ≪[R] 프로그램 흐름제어(3)-기본 문법 활용하기≫은(는) 크리에이티브 커먼즈 저작자표시-비영리-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.
이 라이선스의 범위 이외의 이용허락을 얻기 위해서는 leekh4232@gmail.com으로 문의하십시오.

[R] 프로그램 흐름제어(3)-기본 문법 활용하기

if, while, for 문은 각각의 블록({}) 안에 같은 종류의 구문 혹은 다른 종류의 구문을 포함할 수 있습니다.

#01. 자주 사용되는 문법 패턴

자주 사용되는 문법의 중첩 패턴은 아래와 같다.

  • if - if
  • for - if
  • for - for

    1) if문 간의 중첩

하나의 조건을 좀 더 세분화 하여 판별하고자 할 경우 사용한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
point <- 78

if (point > 70) {
    print ("패스입니다.")

    if (point > 90) {
        print("A입니다.")
    } else if (point > 80) {
        print("B입니다.")
    } else {
        print("C입니다.")
    }
} else {
    print("패스하지 못했습니다.")
}
▶ 출력결과
1
2
[1] "패스입니다."
[1] "C입니다."

2)for문과 if문의 중첩

주로 반복되는 index값에 대한 조건을 판별하고자 하는 경우 사용한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
x <- 0
y <- 0

# -> 1~10까지 반복 수행
for (i in seq(1, 10)) {
    if (i %% 2 == 0) {  # 어떤 수를 2로 나눈 나머지가 0이면 짝수
        print( sprintf("%d(은)는 짝수", i) )
        x <- x + i
    } else {            # 그렇지 않으면 홀수
        print( sprintf("%d(은)는 홀수", i) )
        y <- y + i
    }
}
print( sprintf("1~10까지 짝수들의 합: %d", x) )
print( sprintf("1~10까지 홀수들의 합: %d", y) )
▶ 출력결과
1
2
3
4
5
6
7
8
9
10
11
12
[1] "1(은)는 홀수"
[1] "2(은)는 짝수"
[1] "3(은)는 홀수"
[1] "4(은)는 짝수"
[1] "5(은)는 홀수"
[1] "6(은)는 짝수"
[1] "7(은)는 홀수"
[1] "8(은)는 짝수"
[1] "9(은)는 홀수"
[1] "10(은)는 짝수"
[1] "1~10까지 짝수들의 합: 30"
[1] "1~10까지 홀수들의 합: 25"

3) 2중 반복문

바깥의 반복문이 1회 수행되는 동안 안쪽의 반복문이 매번 처음부터 리셋되어 수행된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 출력에 사용할 문장 형식
tpl = "%d x %d = %d"

# i의 변화범위 2부터 9까지
for (i in seq(2, 9)) {
    # i가 1 증가하는 동안 j의 값이 매번 1~9까지 새로 시작
    for (j in seq(1, 9)) {
        k <- i * j
        print( sprintf(tpl, i, j, k) )
    }

    if (i < 9) {
        print("---------------------")
    }
}
▶ 출력결과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[1] "2 x 1 = 2"
[1] "2 x 2 = 4"
[1] "2 x 3 = 6"
[1] "2 x 4 = 8"
[1] "2 x 5 = 10"
[1] "2 x 6 = 12"
[1] "2 x 7 = 14"
[1] "2 x 8 = 16"
[1] "2 x 9 = 18"
[1] "---------------------"
[1] "3 x 1 = 3"
[1] "3 x 2 = 6"
[1] "3 x 3 = 9"
[1] "3 x 4 = 12"
[1] "3 x 5 = 15"
[1] "3 x 6 = 18"
... 생략 ...
[1] "8 x 8 = 64"
[1] "8 x 9 = 72"
[1] "---------------------"
[1] "9 x 1 = 9"
[1] "9 x 2 = 18"
[1] "9 x 3 = 27"
[1] "9 x 4 = 36"
[1] "9 x 5 = 45"
[1] "9 x 6 = 54"
[1] "9 x 7 = 63"
[1] "9 x 8 = 72"
[1] "9 x 9 = 81"

#02. 자주 등장하는 문제 패턴

1) 별찍기

2중 반복문에서 바깥의 반복이 수행되는 동안 내부의 반복문이 수행할 범위를 동적으로 결정할 수 있는가를 확인하는 문제

순차 출력

2중 반복문에서 바깥의 반복은 을 담당. 안쪽의 반복은 을 담당한다.

1
2
3
4
5
6
7
8
9
10
11
12
for (i in seq(0, 4)) {        # 총 10행이라는 의미
    star <- ""

    for (j in seq(0, i)) {  # 각 행마다 출력될 열의 수를 결정
        # paste0(a, b) 는 a와 b를 공백 없이 결합하여 반환함.
        star <- paste0(star, "*")
        #print(sprintf("i=%d, j=%d", i, j))
    }

    print(star)
    #print("---")
}
▶ 출력결과
1
2
3
4
5
[1] "*"
[1] "**"
[1] "***"
[1] "****"
[1] "*****"

역순출력

1
2
3
4
5
6
7
8
9
for (i in seq(0, 4)) {
    star <- ""

    for (j in seq(i, 4)) {
        star <- paste0(star, "*")
    }

    print(star)
}
▶ 출력결과
1
2
3
4
5
[1] "*****"
[1] "****"
[1] "***"
[1] "**"
[1] "*"

2) 백터의 역순 배치

원본 백터를 아래와 같이 준비한다.

1
2
3
# 원본 백터
my_vector <- c(5, 3, 7, 1, 9)
my_vector
▶ 출력결과
1
2
3
4
5
1. 5
2. 3
3. 7
4. 1
5. 9

배열의 전체 길이를 확인한다.

1
2
3
# 백터의 길이 --> 5
size <- length(my_vector)
size
▶ 출력결과
1
5

백터를 역순으로 재배치 하기 위해서는 전체 길이의 반만큼만 반복을 수행해야 한다. 이 때 백터의 길이가 홀수인 경우 가운데 원소는 위치 변경이 필요 없으므로 나눗셈의 나머지를 버리고 정수부분의 몫만 취한다.

1
2
3
# 백터의 길이를 2로 나눈 정수 부분의 몫 --> 2
half <- size %/% 2
half
▶ 출력결과
1
2

반복을 수행하면서 백터의 현재 위치와 반대쪽에 위치한 원소의 위치를 구해 서로 맞바꾸는 로직을 구현해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 백터의 반 만큼만 반복 수행 --> 1부터 2까지
for (i in seq(1, half)) {
    # i번째 항목의 반대쪽에 위치한 원소의 인덱스를 구한다.
    p <- size - i + 1

    print( sprintf("i=%d, p=%d / x=%d, y=%d", i, p, my_vector[i], my_vector[p]) )

    # i번째 항목과 p번째 항목을 맞교환
    x <- my_vector[i]
    my_vector[i] <- my_vector[p]
    my_vector[p] <- x
}

# 결과출력
my_vector
▶ 출력결과
1
2
3
4
5
6
7
8
[1] "i=1, p=5 / x=5, y=9"
[1] "i=2, p=4 / x=3, y=1"

1. 9
2. 1
3. 7
4. 3
5. 5

3) 백터의 정렬

1
2
3
# 원본 백터
my_vector <- c(5, 3, 7, 1, 9)
my_vector
▶ 출력결과
1
2
3
4
5
1. 5
2. 3
3. 7
4. 1
5. 9
1
2
3
# 백터의 길이 --> 5
size <- length(my_vector)
size
▶ 출력결과
1
5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 처음부터 뒤에서 두 번째것 까지만 반복
for (i in seq(1, size-1)) {
    # i번째 다음부터 끝까지 반복
    for (j in seq(i+1, size)) {
        if (my_vector[i] > my_vector[j]) {
            # i번째 원소와 j번째 원소의 값을 맞바꾼다.
            x <- my_vector[i]
            my_vector[i] <- my_vector[j]
            my_vector[j] <- x
        }
    }
}

my_vector
▶ 출력결과
1
2
3
4
5
1. 1
2. 3
3. 5
4. 7
5. 9
Rating:

크리에이티브 커먼즈 라이선스 ITPAPER(호쌤,쭈쌤)에 의해 작성된 ≪[R] 프로그램 흐름제어(3)-기본 문법 활용하기≫은(는) 크리에이티브 커먼즈 저작자표시-비영리-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.
이 라이선스의 범위 이외의 이용허락을 얻기 위해서는 leekh4232@gmail.com으로 문의하십시오.

comments powered by Disqus