인프런 커뮤니티 질문&답변

David님의 프로필 이미지
David

작성한 질문수

나도코딩의 자바 기본편 - 풀코스 (20시간)

퀴즈#6에서 쓰인 substring 메소드의 작동 원리?

해결된 질문

작성

·

356

0

안녕하세요, 선생님. 다름이 아니라 제가 퀴즈#6을 풀면서, substring의 작동원리에 대해서 궁금한 것이 생겨 이렇게 질문을 남깁니다...ㅎ

public static String getHiddenData(String data, int index)
{
   String hiddenData = data.substring(0, index);
   // for (i = index; i < data.length(); i++) { ... }
   for (int i = 0; i < data.length() - index; i++;) {
      hiddenData += "*";
   }
   return hiddenData;
}

public static String getHiddenData(String data, int index) {...}; 메소드에서, 처음 저장 될 데이터 hiddenData 에서 우선 대입 연산자 =를 통해 data.substring(0, index);를 저장하고, String으로 저장된 문자열을 0번째 인덱스부터 index 직전 자리까지 정상적으로 문자열을 main 메소드를 통해 출력을 한 다음, for문을 통해서 index 이후 자리부터는 일반적인 문자열 대신 별표(*)로 덮어쓰고 출력하는 걸로 이해했는데, 제가 올바르게 이해 한 걸까요?...ㅎ

이전에 같은 substring 개념을 이용한 퀴즈#3은 문제를 다시 풀었을 땐 별 무리가 없었는데, 막상 퀴즈#6에서는 메소드의 작동 원리가 눈에 잘 안 들어오네요...ㅎ 참, 제가 질문 글들을 올릴 때 마다 항상 좋은 답변은 감사합니다...ㅎ 덕분에 어려운 프로그래밍 공부를 나도코딩 선생님 덕에 잘 헤쳐나가고 있습니다...ㅎ

답변 1

1

나도코딩님의 프로필 이미지
나도코딩
지식공유자

안녕하세요?
getHiddenData 의 동작 원리를 하나씩 뜯어서 설명드려보겠습니다 😊
숨기려는 데이터는 "가나다라마바사" 라는 글자 중에서 끝에 2글자인 "바사" 라고 해보겠습니다. 원하는 결과값은 "가나다라마**" 가 되는 것이죠. 이때 '바' 의 index 는 5이므로 getHiddenData() 메소드는 다음과 같이 호출하면 되겠습니다.

getHiddenData("가나다라마바사", 5); // 문자열, 비공개 시작 index

메소드는 우선 이렇게 생겼습니다. 주석 부분은 제외하였습니다.

public static String getHiddenData(String data, int index)
{
    String hiddenData = data.substring(0, index);
    for (int i = 0; i < data.length() - index; i++;) {
        hiddenData += "*";
    }
    return hiddenData;
}

먼저 첫 번째 문장을 실행하면 data 변수의 값, 즉 "가나다라마바사" 중에서 인덱스 기준으로 0 부터 5 직전까지를 잘라서 hiddenData 변수에 저장합니다.

String hiddenData = data.substring(0, index);

그래서 hiddenData 에는 "가나다라마" 가 남게 되겠지요.

이제 반복문을 수행합니다. 조건에서 보면 i 는 0 부터 시작하며 i 는 data 변수의 길이에서 index 를 뺀 값보다 작다는 조건을 만족하는 동안 실행합니다.

for (int i = 0; i < data.length() - index; i++;) { ... }

data 에는 "가나다라마바사" 라는 7글자가 들어있으므로 data.length() 는 7이 됩니다. 그리고 index 는 우리가 메소드를 호출할 때 보낸 5가 되겠네요. 즉, for 문의 두번째로 들어가는 조건은 i < 7 - 5 가 되며 정리하면 i < 2 가 됩니다. i 는 0부터 2보다 작다는 조건을 만족하는 동안 수행하므로 i가 0일때, 1일때 각각 수행합니다. 그래서 for 반복문 내의 명령은 두 번만 수행되는 것이죠.

두 번 수행되는 동안 아래 코드가 실행됩니다.

    hiddenData += "*";

이는 hiddenData 의 변수에 들어있는 "가나다라마" 라는 문자열에 "*" 를 더해주는 역할을 합니다.

1번 수행되면 "가나다라마*" 가 될 것이고,
2번 수행되면 "가나다라마**" 가 될 것입니다.
3번 수행되면 "가나다라마***" 가 될 것이며,
4번 수행되면 "가나다라마****" 가 되겠네요.

예제에서는 2번만 수행하면 되므로 결국 "가나다라마**" 라는 값이 hiddenData 에 남게 되며 이를 return 을 통해 메소드를 호출한 쪽으로 반환합니다. 그런 다음 main() 메소드에서 이를 출력하면 "가나다라마**" 라는 값이 찍히게 됩니다.

처음에 우리가 전달했던 값이 "가나다라마바사" 이며 그 중에서 "바사" 라는 두 글자를 숨기길 원했으므로 결과적으로 "가나다라마**" 라는 값을 성공적으로 얻게 된 것이죠.

질문주신 내용 중에서 "0번째 인덱스부터 index 직전 자리까지 정상적으로 문자열을 main 메소드를 통해 출력을 한 다음" 부분은 잘못되었습니다. 정상적인 문자열을 main 메소드를 통해 출력하는 것은 아니며 getHiddenData() 메소드 내에서 hiddenData 에 처음으로 저장하는 값이 정상적인 문자열이 됩니다. 여기에 정상적인 문자열을 제외한 숨기려는 문자열 크기만큼 * 을 더하는 것입니다.

질문주신 내용 중에서 "for문을 통해서 index 이후 자리부터는 일반적인 문자열 대신 별표(*)로 덮어쓰고 출력하는 걸로 이해" 부분은 반복문을 이렇게 사용하셨다면 옳은 설명입니다.

for (i = index; i < data.length(); i++) { ... }

하지만 반복문을 이렇게 사용하셨다면 틀린 설명입니다.

for (int i = 0; i < data.length() - index; i++;) { ... }

후자의 경우는 결과는 동일하지만 index 이후 자리라는 것을 명시하지 않았으며 그저 현재 hiddenData 변수에 저장된 문자열 뒤에 주어진 횟수만큼 * 을 붙이는 것이 옳은 설명입니다.

여전히 헷갈리신다면 getHiddendata() 메소드 내에 이렇게 로그를 찍어서 단계별로 값을 확인하시면 도움될거에요 😊

public static String getHiddenData(String data, int index) {
    String hiddenData = data.substring(0, index);
    System.out.println("hiddenData (최초값) : " + hiddenData); // 로그
    for (int i = 0; i < data.length() - index; i++) {
        hiddenData += "*";
        System.out.println("hiddenData (반복문 내에서) : " + hiddenData); // 로그
    }
    System.out.println("hiddenData (최종값) : " + hiddenData); // 로그
    return hiddenData;
}

가령 아래와 같이 phone 정보 및 숨기려는 index (9) 를 전달해볼게요.

String phone = "010-1234-5678";
getHiddenData(phone, 9);

이때 출력되는 결과는 다음과 같습니다.

hiddenData (최초값) : 010-1234-
hiddenData (반복문 내에서) : 010-1234-*
hiddenData (반복문 내에서) : 010-1234-**
hiddenData (반복문 내에서) : 010-1234-***
hiddenData (반복문 내에서) : 010-1234-****
hiddenData (최종값) : 010-1234-****

도움되었으면 좋겠어요 😊
감사합니다.

David님의 프로필 이미지
David

작성한 질문수

질문하기