https://programmers.co.kr/learn/courses/30/lessons/60057#
코딩테스트 연습 - 문자열 압축
데이터 처리 전문가가 되고 싶은 "어피치"는 문자열을 압축하는 방법에 대해 공부를 하고 있습니다. 최근에 대량의 데이터 처리를 위한 간단한 비손실 압축 방법에 대해 공부를 하고 있는데, 문
programmers.co.kr
너무 많은 주석 때문에 가독성이 떨어지지만
자세히 남겨놓아야 나중에 보았을 때 내가 어떤 생각을 했는지 왜 이렇게 작성했는지 알기 쉽기때문에
최대한 자세히 적어놓았다!
풀이 중 내꺼랑 비슷한 건 발견 못했지만... 나름대로 만족하는 나의 코드~!~!
사실 그냥 진짜 제일 짧은 길이만 찾아서 반환하면 되는데
압축한 문자열까지 만들어서 코드가 좀 길어진 면이 없지않아 있다
그래서 약간 수정하여 두 버전이 되어버린...
하나는 제일 짧은 길이를 계속 갱신해서 가지고 있다가 return 해주는 거고
하나는 압축한 문자열 배열을 만들고 그 중 가장 짧은 문자열의 length를 return 해주는 것이다~~~
1. 목적에 충실히 길이만 return하는 버전
function solution(str) {
var answer = str.length; //answer의 최대값일 str의 길이로 선언 및 초기화
//1. 반복문 - n개의 단위마다 반복
for(var i=1; i<str.length+1; i++){ //n개 = i개 - ex) "ababde" 1~6개 단위
var arr = []; //문자열 조각들에 대한 정보 배열 - ex) i=2일 때, [['ab', 2], ['de', 1]]
//2. 반복문 - 문자열을 조각내어 정보 저장
for(var j=0; j<str.length/i; j++){ //i개로 조각낼 수 있는 만큼 조각내기 - ex) i=2일 때, 6/2=3, 3번
var piece = str.substr(j*i, i); //문자열 조각 - ex) i=2일 때, substr(0, 2), substr(2, 2)...
if(arr.length > 0){ //조각 정보가 이미 있을 경우
if(arr[arr.length-1][0] == piece){ //가장 최근에 넣은 조각과 현재 조각을 비교하여
arr[arr.length-1][1] = arr[arr.length-1][1] + 1 //같으면 개수를 1 증가
}else{
arr.push([piece, 1]); //다르면 새로 넣어주기
}
}else{ //조각 정보가 1개도 없을 경우
arr.push([piece, 1]); //새로 넣어주기
}
}
var len = 0; //압축된 문자열의 길이
arr.forEach((v, i) => {
if(v[1] == 1) len += v[0].length; //1개면 그냥 문자열 길이를 더해주고
else len += v[0].length + String(v[1]).length; //2개 이상이면 개수를 문자열로 바꿔 그 길이도 더해준다
});
if(len < answer) answer = len; //기존 answer보다 len이 작으면 len을 answer에 대입해준다
}
return answer; //answer의 길이 return
}
2. 압축된 문자열까지 알 수 있는 버전
function solution(str) {
var resultStr = []; //n개 단위로 잘라 압축한 문자열 배열
//1. 반복문 - n개의 단위마다 반복
for(var i=1; i<str.length+1; i++){ //n개 = i개 - ex) "ababde" 1~6개 단위
var arr = []; //문자열 조각들에 대한 정보 배열 - ex) i=2일 때, [['ab', 2], ['de', 1]]
//2. 반복문 - 문자열을 조각내어 정보 저장
for(var j=0; j<str.length/i; j++){ //i개로 조각낼 수 있는 만큼 조각내기 - ex) i=2일 때, 6/2=3, 3번
var piece = str.substr(j*i, i); //문자열 조각 - ex) i=2일 때, substr(0, 2), substr(2, 2)...
if(arr.length > 0){ //조각 정보가 이미 있을 경우
if(arr[arr.length-1][0] == piece){ //가장 최근에 넣은 조각과 현재 조각을 비교하여
arr[arr.length-1][1] = arr[arr.length-1][1] + 1 //같으면 개수를 1 증가
}else{
arr.push([piece, 1]); //다르면 새로 넣어주기
}
}else{ //조각 정보가 1개도 없을 경우
arr.push([piece, 1]); //새로 넣어주기
}
}
//i개로 잘라 압축한 문자열 생성하기
var makeStr = "";
arr.forEach((v, i) => {
if(v[1] == 1) makeStr += v[0]; //1개면 그냥 문자열 그대로 넣기 - ex) ["de", 1] => "ab"
else makeStr += (String(v[1]) + v[0]); //2개 이상이면 개수를 문자열로 바꿔 앞에 붙혀주기 - ex) ["ab", 2] => "2ab"
});
resultStr.push(makeStr); //단위별로 압축한 문자열을 resultStr에 넣어주기
}
var answer = resultStr[0]; //첫번째 문자열을 answer 세팅
for(var i=1; i<resultStr.length; i++){
if(answer.length > resultStr[i].length) answer = resultStr[i]; //더 짧은 문자열이 있으면 answer에 세팅
}
return answer.length; //answer의 길이 return
}
끝!! 레벨 2가 더 재밌긴한거같다
728x90
반응형