// 80byte 기준으로 잘라서 배열에 담기
// 한글은2byte, 한글을 제외한 영어, 숫자, 기호, 띄어쓰기는 1byte
// 자르고 난 다음 글자가 공백일 경우는 생략처리
let str ="이 글은 도커에 대해 1도 모르는 시스템 관리자나 서버 개발자를 대상으로 도커 전반에 대해 얕고 넓은 지식을 담고 있습니다. 도커가 등장한 배경과 도커의 역사, 그리고 도커의 핵심 개념인 컨테이너와 이미지에 대해 알아보고 실제로 도커를 설치하고 컨테이너를 실행해 보도록 하겠습니다.";
해당 문제였고... 나름 수업 시간과 끝나고 힌트도 얻을 겸 여쭤봐서 원하는 값을 도출해냈다.
다른 사람들이 올린 코드는 좀더 깔끔하던데 나는 아직도 멀었나보다 ㅜ,ㅜ
--- 접근법 ---
- 일단 한글인지 아닌지 구분해줄 수 있는(특정 패턴의 문자열을 찾는) RegExp, 정규표현식을 서칭해보았다. 인턴으로 일할 때 비속어 같은 걸 json으로 읽어와서 **으로 바꿔주는 형식을 사용했던게 떠올랐기 때문이다.
- 자바스크립트에선 정규표현식의 내장 함수 중 test() 라는 함수가 있다. 이는 test()에 매개변수로 들어가는 문자열을 확인하며 해당 정규표현식에 해당하는 문자가 있다면 true를 반환한다고 한다.
- 정규표현식은 new RegExp() 으로 만들수도 있고, 바로 /[ ]/ 로 넣어줄 수도 있다고 함
- 그리고 byte 계산을 해줄 변수와 80바이트를 채워주면 잘라줄 idx 변수를 지정해주고, idx를 리턴해주는 함수를 작성한다.
- 문자열에서 문자에 하나씩 접근하기 위해서 charAt()을 사용했다. 이를 test() 와 함께 사용하여 조건식을 써주었고, 따로 점수를 확인하는 boolean을 리턴하는 함수를 작성해줬다.
- byte를 검사하고 난 글자들은 replace()로 임의대로 검사할 수 없는 문자인 *로 바꿔주었다.
- 갯수를 담아줄 배열과 결과를 도출할 배열 두개를 선언해준 뒤, 갯수를 담은 배열을 문자열을 반복문을 돌면서 splitToArray 함수를 실행하여 뽑아내준다.
- 다만 80바이트를 미처 못 채우는 마지막 줄은 제대로된 idx값이 리턴되지 않으므로 그걸 감안하여 마지막 배열은 문자열의 길이를 넣어준다.
- slice() 로 idx만큼 쪼개어 잘라준다...
다른 사람들 코드를 보니까 .charCodeAt() 이라는 메서드를 사용하던데 ?
전혀 모르는 메서드라 검색 고고..
오오 그렇구나.... 신기하다
str.charCodeAt(index) 형식으로 사용하며 문자의 유니코드를 리턴한다는데 charAt()과 비슷하면서도 다르다.
한글의 유니코드 값을 알면 저렇게도 풀수 있겠구나(나는 생각도 안해봣음) 싶었다.
let copyStr = str.slice(0); //원본 데이터는 그대로
function splitToArray (str) {
const korean = /[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/; //한글
const notKorean = /[\s|0-9|a-zA-Z]/; //영어, 숫자, 띄어쓰기
let byte = 0;
let idx = 0;
// 문자열을 하나씩의 문자로 뽑아낸 뒤, 그 문자를 정규표현식으로 한글/공백/문자 확인
for (let i = 0; i < copyStr.length; i++) {
let tmpChar = copyStr.charAt(i);
if ( korean.test(tmpChar) === true ) {
byte += 2;
if(checkScore(byte) == false) {
byte -= 2;
idx = i;
break;
}
} else if ( notKorean.test(tmpChar) === true ) {
byte += 1;
if(checkScore(byte) == false) {
byte -= 1;
idx = i;
break;
}
}
copyStr = copyStr.replace(tmpChar, "*");
//확인한 문자는 *로 치환해서 다시 검사 안하게함
}
return idx;
}
function checkScore(sc) {
if(sc > 80)
return false;
else
return true;
}
// 실제 로직
let idxStorage = []; //갯수를 담은 배열
for (let j = 0; j < copyStr.length; j++) {
let tmpChar = copyStr.charAt(j);
if ( tmpChar === '*' )
continue;
else
idxStorage.push(splitToArray(copyStr));
}
// 예외사항 :: 80바이트가 채 되지 못한 마지막 줄 글자들의 경우 idx가 0이 리턴될 수 있음
if(idxStorage[idxStorage.length - 1] === 0) {
idxStorage.pop();
idxStorage.push(copyStr.length); // 갯수를 담은 배열의 끝을 문자열 길이만큼으로 변경
}
console.log(idxStorage);
let result = []; // 결과용 배열
let prev = 0;
for (let i = 0; i < idxStorage.length; i++) {
result[i] = str.slice(prev, idxStorage[i]).trim();
prev = idxStorage[i];
}
console.log(result);
자바스크립트로 처음 풀어보는 문제...!!!!
매번 개념만 공부하다가 해보니까 어렵고 신선했다.
특히 C#으로 코테 공부했을 때가 새록새록 생각나서 문제 푸는거와 별개로... 재미있었다. 근데 좀 비효율적으로 짠거 같기도 ㅋㅋㅋ
'학원에서 배운 것 > JavaScript' 카테고리의 다른 글
KDT 5th 웹개발자 입문 수업 14일차 (0) | 2023.02.14 |
---|---|
KDT 5th 웹개발자 입문 수업 13일차 (0) | 2023.02.13 |
KDT 5th 웹개발자 입문 수업 12일차 (0) | 2023.02.10 |
KDT 웹개발자 입문 수업 11일차 - 2 (0) | 2023.02.09 |
자바스크립트 맛보기 (0) | 2023.02.02 |