데일리 코딩을 풀며 정확히 이해하지 못했거나 틀린 문제로 남겨두었던 문제들을 Section이 끝난 기념으로 총 정리 해보았습니다.
** 13번 과 17번은 미해결 문제 입니다..
Problem 04
# 각 문자열의 첫 글자로 이루어진 문자열 리턴
- Ex. 입력 : 'hello world" 출력 : "hw"
function firstCharacter(str){ const answer = str.split(' '); let arr = []; let result = []; if( str.length === 0) { return ''; } for( let i fo answer){ arr = i.split(''); for( let j = 0 ; j <1; j++){ //맨 첫 글자만 필요함 result.push(arr[j]); } } result = result.join(''); //배열을 다시 문자열로 합치기 return result; }
# 1차 풀이 :
입력 받은 문자열들을 이중 for문을 돌면서 각 문자열의 첫 번째 요소에 접근 후 새로운 배열에 넣어주었다. 그리고 join 메서드로 다시 문자열로 합치는 과정을 통해 테스트를 통과
function firstCharacter(str) { if (str === '') { return ''; } let words = str.split(' '); let result = ''; for (let i = 0; i < words.length; i ++) { result += words[i][0]; } return result; }
# 2차 풀이 :
굳이 이중 for문을 돌릴 필요 없이 이차원 배열로 각 요소의 첫 번째 요소를 뽑아서 문자열 변수 result에 바로 넣어줄 수 있다.
Problem 10
# 문자열을 입력 받아 연속된 한 자리 홀수 숫자 사이에 '-' 을 추가한 문자열을 리턴해야 한다.
- EX 입력 : '454793' 출력 : 4547-9-3
function insertDash(str) { let result = str[0]; for( let i = 1 ; i<str.length; i++){ if( Number(str[i-1])%2 !== 0 && Number(str[i])%2 !== 0 ){ result = result + '-'; } result = result + str[i]; } return result; }
# 1차 풀이 :
문자열의 [0] 요소를 미리 result 변수 안에 선언을 해준 뒤, for문을 통해 문자열의 요소에 접근을 시도합니다.
만약 이전 요소와 다음 요소가 모두 홀수라면 if문 에서 ' - ' 을 추가한 후 str[i]을 넣는 방식으로 진행합니다. 홀수가 아니라면 if문을 건너띄고 바로 str[i]를 집어넣습니다.
** for문을 돌릴 때 이미 str[0]가 result 변수 안에 있으므로 str[1] 번재 요소부터 진행하는 것이 좋을 듯 합니다.
Problem 12
# 이중 for문으로 각 행의 각 열 요소에 접근하기
let arr = [ ['a', 'a', 'b'], ['a', 'a,' 'a'], ['a', 'a', 'a'], ]; for( let i = 0 ; i < arr.lenfth; i++){ for( let j = 0; j < arr[i].length; j++)}{ // 1. 1차 실수 if( arr[i][j] === 'b'){ // 2. 2차 실수 console.log( [i, j] ); // [0, 2] } } }
# 1차 실수 :
단순히 arr[j] 만 원하는 값인 'b' 를 찾는 if문 을 조건으로 지정하였으나, 그렇게 되면 계속 'undefined ' 가 출력 됩니다.
i 행을 돌면서 그 안에 요소에 접근하기 위해서 단순히 i.length 길이 만큼 돌려버렸으나, 이는 첫 번째 행의 경우 0 만큼 돌고 두번째 행은 1까지만 돌리는 결과가 되어버렸습니다.
arr[i] 처럼 배열의 길이로 지정을 해주어야 우리가 원하는 결과를 얻을 수 있습니다.
# 2차 실수 :
아마도, arr은 이차원 배열이기 때문에 i 행의 j 요소라는 정확한 위치를 지정하여 if문을 걸어야 하는 것 같습니다.
참고 블로그 : 1,2차원 배열 선언 및 초기화
Problem 13
# 13번 readVertically
- 문자열을 요소로 갖는 배열을 입력 받아 문자열을 세로로 읽었을 때의 문자열을 리턴해야 합니다.
- ex. 입력 : [ 'hello', 'world'] 출력 : 'hweolllrod'
# 1차 풀이
function readVertically(arr) { let temp = []; for (let i = 0; i < arr.length; i++) { let str = arr[i]; for (let j = 0; j < str.length; j++) { if (temp.length === j) { temp.push(str[j]); } else { temp[j] = temp[j] + str[j]; } } } let result = ''; for (let i = 0; i < temp.length; i++) { result = result + temp[i]; } return result; }
# 2차 풀이 - 레퍼런스
잘 모르겠다.
Problem 17
# 수를 입력 받아 제곱근 값을 소수점 두 자리까지 리턴
Ex. 입력 : 9 출력 : 3 , 입력 : 6 출력 : 2.45
function computeSquareRoot(num) { let answer = 0; for( let i = 1 ; i <= num/2; i++){ if( i* i === num){ answer = i; } } answer = (num/2).toFixed(2) // 1차 실수 return answer; }
# 1차 실수 :
단순히 나눠서 소수점 2자리까지 출력하게 하면 안되었습니다..
function computeSquareRoot(num) { const diffs = [1, 0.1, 0.01, 0.001]; let base = 1; for (let i = 0; i < diffs.length; i++) { while (base * base < num) { base = base + diffs[i]; } if (base * base === num) { return base; } else { base = base - diffs[i]; } } return Number(base.toFixed(2)); }
# 2차 풀이 - 레퍼런스 -
잘 모르겠다.
** 바빌로니아 법 - 제곱근을 구하는 방법 중 하나 (바빌로니아 법의 점화식)
Problem 18
# 문자열을 입력받아 문자열에서 숫자를 모두 더한 뒤 해당 값을 문자열의 길이로 나눈 값을 정수로 반올림하여 리턴
- Ex 입력 : 'Hello6' 출력 : 1 --> 문자 길이 6 / 문자열 내 숫자 6 :: 6 / 6 = 1
function numberSearch(str) { let sum = 0; let arr = []; const digits = '0123456789'; let answer = 0; let cnt = 0; if(str === ''){ return 0; } arr = str.split(''); for( let i = 0 ; i < arr.length; i++){ if( digits.includes(arr[i])){ sum += Number(arr[i]); cnt++; } if(arr[i] === ' '){ cnt ++; } } return (Math.round(sum/(str.length-cnt))); }
# 1차 풀이
digits 변수에 string 타입의 0 - 9 을 미리 선언을 한 뒤 includes 함수를 이용해서 각 for문의 요소가 digits 변수와 겹치는 부분이 있는지를 거른 뒤에 해당 요소를 Number() 로 타입을 변환하여 sum에 누적 덧셈을 해줍니다.
* sum = 문자열 요소 내의 숫자 부분을 누적 더한 값
같은 if 문 안에서 cnt 요소의 후위 증가를 해줌으로써 숫자를 찾을 때마다 카운트 , 그리고 바깥 if 문 조건에서 공백 부분을 찾을 때도 카운트를 해줌으로써 나중에 최종 str.length에서 공백과 숫자를 뺀 길이를 알 수 있습니다.
마지막에 문제에서 원하는 조건에 맞추어 Math.round(반올림 )메소드를 사용하여 값을 return 해주었습니다.
function numberSearch(str) { const digits = '0123456789'; if (str === '') { return 0; } let sum = 0; let pureStr = ''; for (let i = 0; i < str.length; i += 1) { if (digits.includes(str[i])) { // 숫자인 경우 sum = sum + Number(str[i]); } else if (str[i] !== ' ') { // 숫자도 공백도 아닌 경우 ************* pureStr = pureStr + str[i]; } } // 결과를 반올림 한다. return Math.round(sum / pureStr.length); }
# 2차 풀이 - 레퍼런스
else if 문 조건으로 첫 번째 조건에서 숫자인 경우를 거르고 공백도 아닌 경우를 거름으로써 1차 풀이의 str.length - cnt 를 간편하게 pureStr 로 구할 수 있게 되었습니다.
Problem 19
# 암호화된 문자열과 암호화 키를 입력 받아 복호화된 문자열을 리턴해야 합니다.
** 카이사르 암호(Caesar cipher)는 평문(plaintext)을 암호화키 갯수만큼 오른쪽으로 평행 이동 시켜 암호화 합니다.
- Ex 입력 : 'hello' / secret : 3 출력 : 'khoor'
* h --> k * e --> h * l--> o * o --> r
# 1차 풀이 - 레퍼런스function decryptCaesarCipher(str, secret) { str = str.toUpperCase(); let newStr = ''; for( let i = 0 ; i< str.length; i ++){ if(str[i] === ' '){ newStr += ' '; } else{ newStr += String.fromCodePoint(str.charCodeAt(i)-secret); } } return newStr.toLowerCase(); }
문자를 아스키코드로 변환하는 charCodeAt ()과 반대인 String.fromCodePoint()메서드를 사용하려 하였으나 실패.
이유는 secret 에 할당 되는 숫자가 아스키코드 기준인 'A' 65 이하로 넘어가면 다른 문자나 기호로 변화되기 때문에 몇 예제들은 테스트를 통과하지 못합니다.
function decryptCaesarCipher(str, secret) { // 알파벳 let alpha = 'abcdefghijklmnopqrstuvwxyz'; let result = ''; for (let i = 0; i < str.length; i++) { if (str[i] === ' ') { // 공백은 그대로 둔다. result = result + ' '; } else { // 현재 문자의 알파벳 순서를 구한다. let asis = alpha.indexOf(str[i]); // 복호화는 반대 방향으로 이루어기 때문에 seceret을 뺀다. let tobe = (asis - secret + alpha.length) % alpha.length; result = result + alpha[tobe]; } } return result; }
# 2차 풀이 - 레퍼런스첫 번째 조건문의 공백은 그대로 공백으로 넣어주는 것 까지는 동일하지만 두 번째 else 문에서부터 다릅니다.
for문으로 순회하는 str[ i ] 가 미리 선언한 alpha 변수의 값과 일치하는 순서를 indexOf 메서드를 통해 asis 변수에 할당합니다. 예를 들어, str[ i ]가 ' b '라면 asis의 ' b '의 위치인 1 이 asis에 할당됩니다. 이를 가지고 - secret 을 통해 원래의 평문을 추측할 수 있습니다.
[1] tobe 변수에서 1차 풀이에서 실패한 기준 문자열 이후로 넘어가는 문제를 ( asis - secret + alpha.length )를 통해 a 뒤로 숫자가 넘어가도 다시 알파벳의 끝에서부터 역순으로 원하는 값에 접근할 수 있게 되었습니다.
[2] 반대로 기준 a 를 넘어가지 않더라도 마지막에 % alpha.length를 통해 앞에서부터 원하는 값에 접근할 수도 있습니다.
indexOf [0] [1] [2] [3] [4] ... [23] [24] [25]
alpha a b c d e ... x y z ( 총 갯수 : 26개 )
>> str [ i ] = 'e' , secret = 3 일 때,
asis = 4가 되고, tobe = ( 4 - 3 + 26) % 26; = 1 이므로 alpha[ tobe = 1 ] 는 b 가 됩니다. 원하는 조건인 e 왼쪽으로 3칸 이동한 b 를 알맞게 찾은 것을 알 수 있죠.
>> str[ i ] = 'a' , secret = 3 일 때,
asis = 0 이 되고, tobe = ( 0 - 3 + 26 ) % 26; = 23 이므로 alpha [ tobe = 23 ] 는 x 가 됩니다. 원하는 조건인 a 왼쪽으로 3칸 이동한 x 를 알맞게 찾았습니다.
최종적으로 result 에 alpha 변수에 저장 된 문자열들의 알맞은 순서들을 누적 하여 모든 테스트를 통과할 수 있습니다.
Problem 20
# 문자열을 입력 받아 3개 이상 연속되는 문자가 있을 경우, 압축하여 리턴 해야 합니다.
- Ex 입력 : 'wwwggoppopppp' 출력 : 3wggoppo4p
# 1차 풀이function compressString(str) { let count = 0; let arr = []; let w = str; if( str.length === 0){ return '' } for (let i = 0; i < w.length; i++) { let j = w[0]; if (j === w[i]) { count++; if (count >= 3) { w = w.substring(count); arr.push(`${count}${j}`); count = 0; } } } return arr.join(''); }
자꾸 3w 무한 출력이 됩니다.
function compressString(str) { //빈 문자열 처리 if( str === ''){return ''}; let check = str[0]; let cnt = 1; let answer = ''; // ** str의 마지막이 연속되는 숫자일 경우, // 끊어주기 위해 공백 추가 str = str + ' '; for( let i = 1; i < str.length; i++){ if(check === str[i]){ cnt++; }else{ //이전과 다른 문자일 경우, if( cnt >= 3){ answer += `${cnt}${check}`; } else { // cnt 3 미만은 cnt 갯수만큼 반복해서 집어 넣기 answer += check.repeat(cnt); } // 이전과 다른 문자이므로 값 초기화 및 새로운 check 할당 check = str[i]; cnt = 1; } } return answer; }
# 2차 풀이
우선 입력 받을 str의 마지막 부분이 연속되는 문자열일 경우, str 뒤에 공백을 추가해주지 않으면 마지막 연속되는 부분은 else 문에 걸러지지 않아 cnt ++만 수행되고 answer에는 누적되지 않아 반드시 공백으로 끊어주어야 합니다.
** 연속되는 문자의 비교를 위해 check 변수에 문자열의 첫 번째 요소를 할당 합니다. check = str[ 0 ];
for문으로 문자열의 각 요소에 접근하며 check 의 값과 순차적으로 접근하는 문자열 요소의 값이 같으면 cnt ++를 수행합니다. 그러다 check와 다른 문자열을 만나게 되면 else 문으로 넘어가게 됩니다.
이후 누적된 cnt의 값이 3개 이상일 경우 누적된 cnt 값과 해당 문자열인 check 를 함께 출력할 빈 문자열 answer 변수에 넣어줍니다. 반면에 cnt의 값이 3개 미만일 경우 repeat( ) 메소드를 사용하여 cnt의 갯수만큼 반복해서 answer 변수에 넣어줍니다.
>> cnt = 2 일 때, check = 'o' 일 경우,
repeat 메소드에 의하여 answer += ' oo ' 이 할당 됩니다.
else 문 안의 if 조건문을 빠져나오며 모든 값을 초기화 해줌으로써 기존의 연속된 문자열 이후의 새로운 각 문자열들이 동일한 조건들을 순회 할 수 있게 해줍니다.
20번 문제 1차 풀이에서 나온 무한 3w 슈슈슉
피라미드를 이렇게 구현...?