🍋 개요
해당 문제는 제가 2시간 동안 고민해보다 도저히 손을 못 대어서 챗GPT에게 물어봐서 나온 결과물이다. 부족함을 많이 느끼고, 코드라인 마다 디버깅하고 제대로 기억하기 위해서 블로그를 작성하게 되었다. 문제의 코드는 아래와 같다.
문제코드
- 주어진 14바이트의 문자열을 인코딩하여서 반복되는 문자를 특정 로직으로 줄여서 AA는 A2, CCCC는 C4로 만드는 것이다..
- 그리고 디코딩 메소드를 만들어서 인코딩된 문자열을 본래 모습으로 되돌려 놓아야 한다.
🥝 인코딩 메소드
인코딩에서는 각 문자열을 비교하여 반복되는 문자를 count하고 그리고 그 문자와 count된 수를 문자열에 포함시키는 것이 목적이다. 그러기 위해서는 라이브러리에 StringBuilder클래스의
append
기능을 사용하면 내가 원하는 문자를 문자열에 차례로 포함시키면서 업데이트 할 수 있다. 인코딩 메소드의 목표를 요약하면 아래와 같다.- 각 문자열을 비교하여 반복된 수를 구하라
StringBuilder
클래스로append
메소드를 사용할 문자열 객체를 만들어라.
- 그리고 완성된 인코딩 문자열을 반환하라.
첫 번째 작업
- StringBuilder로 선언이 되어야지 나중에 사용할
append
기능을 사용할 수가 있다.
- append기능은 아까 설명했듯이, 내가 원하는 문자를 차례로 문자열에 추가하면서 업데이트 할 수 있는 유용한 기능을 제공한다.
- 비교할 문자를 따로
ch
로 따로 선언해 주었다. 이는 반복문 안에서는 다른 문자를 찾았을 때 시작점을 업데이트가 안되는 번거로움을 해결하기 위함이다.
- 그리고 횟수를 카운트 할
count
도 선언하였다.
StringBuilder 클래스
이 클래스는 Java에서 문자열을 더 효율적으로 다루기 위해서 만들어진 클래스이다. StringBuilder는 변경 가능한 문자열을 다루며, 내부적으로는 문자 배열을 사용하여 문자열을 구성한다. ‘append’메소드를 통해 기존 문자열에 새로운 문자나 문자열을 추가할 수 있으며, 이 과정에서 새로운 객체를 추가하지 않는다.
두 번째 작업
- for 구문에서 현재 문자열과 다음 문자열을 비교 해야 하므로
i = 1
로 초기화 한다.
- else구문으로 넘어왔다는 뜻은 다른 문자를 발견하였다는 뜻이므로 이전 까지의 문자와 반복 횟수는 문자열에 저장이 되어야 한다.
- sb 문자열에
append
메소드를 사용하여 검색 자와 카운팅 횟수를 넣어준다.
- 다음 바뀐 문자를
ch
에 대입하고 카운트도 초기화 한다.
- 마지막 라운드에 저장되지 않은
ch
와count
를for
문 밖에서 저장해준다.
문자를 비교하는데 왜 equals를 쓰지 않았을까??? (중요)
- 여기서 비교하는 것은 문자이고 문자는
equals
로 해야된다고 들었을 것이다. 그런데 왜 비교가 되지 않는 것일까?
- 이는 기본 자료형 타입
int, char, float, double, boolean
의 값은 직접 스택 메모리에 띄어지기 때문이다.equals
는 문자를 비교한다는 개념보다는 힙 메모리에 띄어진 값을 비교한다.
- 예를 들어
s1 = 100, s2 = 100
을 비교하면 스택메모리는 false를 출력하고 힙메모리에서는 true를 반환한다. 바로 그 차이가==
과equals
이다.
🍐 디코딩 메소드
디코딩 메소드는 인코딩으로 변환된 문자열을 다시 원상복구 해야하는 메소드이다. 인코딩 때와는 다르게, 문자와 숫자가 섞여있는 구조이므로 짝수로 순회하는 반복문과 문자를 숫자로 바꾸어 그 수만큼 반복 출력할 수 있게 만드는 메소드가 필요하다. 요약하자면,
- 인코딩된 문자열을 같은 로직으로 되감아서 원상 복구하어야 된다.
- 이 문자열의 특성상 그에 맞는 반복문을 만든다.
- 문자가 숫자로 변환되어 그 수 만큼 반복 입력할
append
메소드도 필요하다.
첫 번째 작업
- StringBuilder 객체를 생성한다.
- 짝수 인덱스에 알파벳 문자가 저장되어 있으므로, 짝수로 순회하는 반복문을 만든다.
- 해당 인덱스의 알파벳은
ch
에 대입하고 뒷 자리 숫자로 된 문자는Character.getNumericValue
로 숫자값으로 반환한다.
Character.getNumericValue( ) 메소드
이 메소드는 Java 표준 라이브러리에 포함된
“Character”
클래스의 메소드이다. 주어진 문자가 나타내는 숫자 값을 반환하는 메소드로, 문자 ‘8’
이 입력되면 숫자 ‘8’
을 반납하고 문자 ‘A’
의 경우 10
을 반환한다.두 번째 방법
- 빨간 박스 부분의 for문은 반복된 횟수를 나타내는 숫자값
count
를 가지고 알파벳을count
만큼dc
문자열에 넣어주는 반복문을 만든다.
마지막 작업
encoding(data)
로 메소드를 실행하여 반환된 값을 String타입 encoded에 저장
decoding(encoded)
로 메소드를 실행하여 인코딩된값을 String타입 decoded에 저장
encoding(data)
메소드가 클래스 또는 변수없이 메소드가 호출 되어있는데, 이는 해당 메소드가 static
선언이 되어있기 때문이다. static 메소드는 어디에서든 호출 가능하다.🍎 결과
package ex08.example; public class StringEx01_01 { public static String encoding(String data) { StringBuilder sb = new StringBuilder(); int count = 1; char ch = data.charAt(0); for (int i = 1; i < data.length(); i++) { if (data.charAt(i) == ch) { count++; } else { sb.append(ch).append(count); ch = data.charAt(i); count = 1; } } sb.append(ch).append(count); return sb.toString(); } public static String decoding(String encodingData) { StringBuilder decoded = new StringBuilder(); for (int i = 0; i < encodingData.length(); i += 2) { char ch = encodingData.charAt(i); int count = Character.getNumericValue(encodingData.charAt(i + 1)); for (int j = 0; j < count; j++) { decoded.append(ch); } } return decoded.toString(); } public static void main(String[] args) { String data = "AABBBCCCCDDDDD"; String encoded = encoding(data); System.out.println("Encoded: " + encoded); String decoded = decoding(encoded); System.out.println("Decoded: " + decoded); } }
- 인코딩 디코딩 알고리즘이 완성되엇다.
- 하지만 이것을 쓰기위해서는 기존 대입할 정렬이 클러스터화가 되어있어야 할 것이다.
- 결과 값또한 의도했던 대로 잘 나온다.
Share article