JAVA 인코딩/디코딩 알고리즘

#JAVA012 #알고리즘 #인코딩 #디코딩
Dec 28, 2023
JAVA 인코딩/디코딩 알고리즘
 

🍋 개요

해당 문제는 제가 2시간 동안 고민해보다 도저히 손을 못 대어서 챗GPT에게 물어봐서 나온 결과물이다. 부족함을 많이 느끼고, 코드라인 마다 디버깅하고 제대로 기억하기 위해서 블로그를 작성하게 되었다. 문제의 코드는 아래와 같다.
 
문제코드
notion image
  • 주어진 14바이트의 문자열을 인코딩하여서 반복되는 문자를 특정 로직으로 줄여서 AA는 A2, CCCC는 C4로 만드는 것이다..
  • 그리고 디코딩 메소드를 만들어서 인코딩된 문자열을 본래 모습으로 되돌려 놓아야 한다.
 

🥝 인코딩 메소드

인코딩에서는 각 문자열을 비교하여 반복되는 문자를 count하고 그리고 그 문자와 count된 수를 문자열에 포함시키는 것이 목적이다. 그러기 위해서는 라이브러리에 StringBuilder클래스의 append기능을 사용하면 내가 원하는 문자를 문자열에 차례로 포함시키면서 업데이트 할 수 있다. 인코딩 메소드의 목표를 요약하면 아래와 같다.
 
  • 각 문자열을 비교하여 반복된 수를 구하라
  • StringBuilder클래스로 append메소드를 사용할 문자열 객체를 만들어라.
  • 그리고 완성된 인코딩 문자열을 반환하라.
 
 

첫 번째 작업

notion image
  • StringBuilder로 선언이 되어야지 나중에 사용할 append 기능을 사용할 수가 있다.
  • append기능은 아까 설명했듯이, 내가 원하는 문자를 차례로 문자열에 추가하면서 업데이트 할 수 있는 유용한 기능을 제공한다.
  • 비교할 문자를 따로 ch로 따로 선언해 주었다. 이는 반복문 안에서는 다른 문자를 찾았을 때 시작점을 업데이트가 안되는 번거로움을 해결하기 위함이다.
  • 그리고 횟수를 카운트 할 count도 선언하였다.
 
💡
StringBuilder 클래스 이 클래스는 Java에서 문자열을 더 효율적으로 다루기 위해서 만들어진 클래스이다. StringBuilder는 변경 가능한 문자열을 다루며, 내부적으로는 문자 배열을 사용하여 문자열을 구성한다. ‘append’메소드를 통해 기존 문자열에 새로운 문자나 문자열을 추가할 수 있으며, 이 과정에서 새로운 객체를 추가하지 않는다.
 

두 번째 작업

notion image
  • for 구문에서 현재 문자열과 다음 문자열을 비교 해야 하므로i = 1로 초기화 한다.
  • else구문으로 넘어왔다는 뜻은 다른 문자를 발견하였다는 뜻이므로 이전 까지의 문자와 반복 횟수는 문자열에 저장이 되어야 한다.
  • sb 문자열에 append메소드를 사용하여 검색 자와 카운팅 횟수를 넣어준다.
  • 다음 바뀐 문자를 ch에 대입하고 카운트도 초기화 한다.
  • 마지막 라운드에 저장되지 않은 chcountfor문 밖에서 저장해준다.
 
 
문자를 비교하는데 왜 equals를 쓰지 않았을까??? (중요)
notion image
  • 여기서 비교하는 것은 문자이고 문자는 equals로 해야된다고 들었을 것이다. 그런데 왜 비교가 되지 않는 것일까?
  • 이는 기본 자료형 타입 int, char, float, double, boolean의 값은 직접 스택 메모리에 띄어지기 때문이다. equals는 문자를 비교한다는 개념보다는 힙 메모리에 띄어진 값을 비교한다.
  • 예를 들어 s1 = 100, s2 = 100 을 비교하면 스택메모리는 false를 출력하고 힙메모리에서는 true를 반환한다. 바로 그 차이가 ==equals이다.
 
 

🍐 디코딩 메소드

디코딩 메소드는 인코딩으로 변환된 문자열을 다시 원상복구 해야하는 메소드이다. 인코딩 때와는 다르게, 문자와 숫자가 섞여있는 구조이므로 짝수로 순회하는 반복문과 문자를 숫자로 바꾸어 그 수만큼 반복 출력할 수 있게 만드는 메소드가 필요하다. 요약하자면,
 
  • 인코딩된 문자열을 같은 로직으로 되감아서 원상 복구하어야 된다.
  • 이 문자열의 특성상 그에 맞는 반복문을 만든다.
  • 문자가 숫자로 변환되어 그 수 만큼 반복 입력할 append메소드도 필요하다.
 
 

첫 번째 작업

notion image
  • StringBuilder 객체를 생성한다.
  • 짝수 인덱스에 알파벳 문자가 저장되어 있으므로, 짝수로 순회하는 반복문을 만든다.
  • 해당 인덱스의 알파벳은 ch에 대입하고 뒷 자리 숫자로 된 문자는 Character.getNumericValue로 숫자값으로 반환한다.
 
💡
Character.getNumericValue( ) 메소드 이 메소드는 Java 표준 라이브러리에 포함된 “Character” 클래스의 메소드이다. 주어진 문자가 나타내는 숫자 값을 반환하는 메소드로, 문자 ‘8’이 입력되면 숫자 ‘8’을 반납하고 문자 ‘A’의 경우 10을 반환한다.
 
 

두 번째 방법

notion image
  • 빨간 박스 부분의 for문은 반복된 횟수를 나타내는 숫자값 count를 가지고 알파벳을 count만큼 dc문자열에 넣어주는 반복문을 만든다.
 
 

마지막 작업

notion image
  • 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); } }
  • 인코딩 디코딩 알고리즘이 완성되엇다.
  • 하지만 이것을 쓰기위해서는 기존 대입할 정렬이 클러스터화가 되어있어야 할 것이다.
 
 
notion image
  • 결과 값또한 의도했던 대로 잘 나온다.
 
 
Share article
RSSPowered by inblog