Search
🥭

#인코딩디코딩알고리즘

개요

해당 문제는 제가 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에 대입하고 카운트도 초기화 한다.
마지막 라운드에 저장되지 않은 chcountfor문 밖에서 저장해준다.
문자를 비교하는데 왜 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); } }
Java
복사
인코딩 디코딩 알고리즘이 완성되엇다.
하지만 이것을 쓰기위해서는 기존 대입할 정렬이 클러스터화가 되어있어야 할 것이다.
결과 값또한 의도했던 대로 잘 나온다.