코로 넘어져도 헤딩만 하면 그만

[알고리즘]9_ABCheck, 10_insertDash, 11_removeExtremes, 12_findBugInApples 본문

CODE STATES 44/데일리 코딩(알고리즘)

[알고리즘]9_ABCheck, 10_insertDash, 11_removeExtremes, 12_findBugInApples

꼬드리 2023. 3. 24. 09:39

09. ABCheck

문자열을 입력받아 문자열 내에 아래 중 하나가 존재하는지 여부를 리턴해야 합니다.

  1. 'a'로 시작해서 'b'로 끝나는 길이 5의 문자열
  2. 'b'로 시작해서 'a'로 끝나는 길이 5의 문자열
  • 대소문자를 구분하지 않습니다.
  • 공백도 한 글자로 취급합니다.
  • 'a'와 'b'는 중복해서 등장할 수 있습니다.
function ABCheck(str) {
  // 문자열을 입력받아 문자열 내에 아래 중 하나가 존재하는지 여부를 리턴해야 합니다.
  // 'a'로 시작해서 'b'로 끝나는 길이 5의 문자열
  // 'b'로 시작해서 'a'로 끝나는 길이 5의 문자열
  //'a'와 'b'는 중복해서 등장할 수 있습니다.
  //대소문자를 구분하지 않습니다.
  //대소문자를 구분하지 않으므로 .toUpperCase 를 써서 비교해주면 될 것 같다.
  //문자열을 .spilt 사용 하여 띄어쓰기로 구분해서 배열로 만들어준다.
  //이후 if문을 사용하여 비교한다.
  let result = str.split(' ');
  //result는 배열이다.
  for (let i = 0; i < result.length; i++) {
    //배열 내부의 한 단어씩 살펴본다.
    //result[i]; 이게 한 단어임
    if (
      result[i].length === 5 &&
      result[0].toUpperCase === 'A' &&
      result[result.length - 1].toUpperCase === 'B'
    ) {
      return true;
    } else if (
      result[i].length === 5 &&
      result[0].toUpperCase === 'B' &&
      result[result.length - 1].toUpperCase === 'A'
    ) {
      return true;
    } else {
      return false;
    }
  }
  console.log(result);
}

let output = ABCheck('lane Borrowed');

처음에 이렇게 풀었는데 문제 이해를 잘못한 것 같다. 나는 5글자, 앞뒤가 조건에 맞는 단어가 존재하면 true를 반환하게 작성했는데, 띄어쓰기가 있건 없건 문자열 내부에 있어도 true가 리턴되야 하는 것이었다. 

 

function ABCheck(str) {
  let string = str.toUpperCase();
  let result;

  for(let i = 0; i < string.length; i++){
    if(string[i] === 'A' && string[i + 4] === 'B') result = true; 
    if(string[i] === 'B' && string[i + 4] === 'A') result = true;
  }

  if(result === undefined) return false;
  return result;

}

결국 위와 같이 코드를 바꾸었다. for문 안에 i를 기준으로 두고 +4를 하여 둘다 조건에 부합할 때만 true를 리턴한다. 

 

 

10. insertDash

문자열을 입력받아 연속된 한자리 홀수 숫자 사이에 '-'를 추가한 문자열을 리턴해야 합니다.

 

function insertDash(str) {
  //문자열을 입력받아 연속된 한자리 홀수 숫자 사이 '-'를 추가한 문자열 리턴
  //0은 짝수이다.
  //join('-')을 쓰면 알맞을 것 같다. <아니다 배열에 쓰는거였지
  let result = '';
  for (let i = 0; i < str.length; i++) {
    result = result + str[i];
    if (str[i] % 2 === 1 && str[i + 1] % 2 === 1) {
      result = result + '-';
    }
  }
  return result;
}

문제 해석을 잘못해서(예시 먼저 읽는 습관을 들여야겠다;) 짝수는 다 빼버리고 홀수만 리턴하는 결과를 만들었다가, 아차 하고 다시 짜봤다. filter()나 forEach()를 써보고 싶었는데 배열이 아니라서 안 된다는 걸 알고 아쉬워졌다. 고차 함수를 더 써보고 싶은데.....  그리고 join()역시 배열에 쓰이는 거다. 문자열 인덱스 + 숫자로 다음 글자 찾는 방법은 위의 문제에서 이미 접해서 쉬웠다. 

 

 

11_removeExtremes

문자열을 요소로 갖는 배열을 입력받아 가장 짧은 문자열과 가장 긴 문자열을 제거한 배열을 리턴해야 합니다.

  • 가장 짧은 문자열의 길이와 가장 긴 문자열의 길이가 같은 경우는 없습니다.
  • 가장 짧은 문자열 또는 가장 긴 문자열이 다수일 경우, 나중에 위치한 문자열을 제거합니다.
function removeExtremes(arr) {
  let shortLen = 20;
  let shortIdx = 0;
  let longLen = 0;
  let longIdx = 0;
  let result = [];

  for (let i = 0; i < arr.length; i++) {
    if (shortLen >= arr[i].length) {
      shortLen = arr[i].length;
      shortIdx = i;
    }
    if (arr[i].length >= longLen) {
      longLen = arr[i].length;
      longIdx = i;
    }
  }

  for (let j = 0; j < arr.length; j++) {
    if (j !== shortIdx && j !== longIdx) {
      result.push(arr[j]);
    }
  }
  return result;
}

나에게는 상당히 까다로운 문제였다. 애초에 Idx랑 Length변수를 각각 만들어줘야 한다는 사실을 모르고 있었다. 이제야 구조가 좀 파악이 되는 듯....... for문 내부에서 일단 가장 짧은 문자열과 긴 문자열의 인덱스를 걸러낸 뒤에, 다른 for문 내부에서 그 인덱스를 갖지 않는 문자열만 새 배열에 담아 리턴해주면 된다.

 

 

12_findBugInApples

2차원 배열(배열을 요소로 갖는 배열)을 입력받아 'B'의 위치 정보를 요소로 갖는 배열을 리턴해야 합니다.

  • 'B'의 위치 정보(행, 열)를 요소로 갖는 배열을 리턴해야 합니다.
  • 행: 'B'를 요소로 갖는 배열 arr[i]의 인덱스 i
  • 열: arr[i]에서 'B'(arr[i][j])의 인덱스 j
  • arr, arr[i]의 길이는 다양하게 주어집니다.
  • 항상 한 개의 문자열 'B'가 존재합니다.
function findBugInApples(arr) {
  // 'B'의 위치 정보(행, 열)를 요소로 갖는 배열을 리턴해야 합니다.
  //배열이 들어온다. 몇 번째 배열에 B가 몇 번째 인덱스로 존재하는지 리턴.
  let result = [];
  for (let i = 0; i < arr.length; i++) {
    for (let j = 0; j < arr[i].length; j++) {
      if (arr[i][j] === 'B') {
        result.push(i);
        result.push(j);
      }
    }
  }
  return result;
}

행과 열, 즉 두 개의 알파벳을 갖는다는 것을 알고 나자 이중 포문을 떠올리기는 쉬웠다. 다만, 빈 배열 변수를 지정해서 push하는 방법 말고 그냥 return [ i, j ]를 했어도 된다는 사실을 새로 알았다... 

Comments