[알고리즘]프로그래머스 0603

정제철·2023년 6월 2일
0

알고리즘

목록 보기
11/12

📢1. 숫자 문자열과 영단어

  • 문제 설명(2021 카카오 채용연계형 인턴십 문제)

    네오와 프로도가 숫자놀이를 하고 있습니다. 네오가 프로도에게 숫자를 건넬 때 일부 자릿수를 영단어로 바꾼 카드를 건네주면 프로도는 원래 숫자를 찾는 게임입니다.
  • 다음은 숫자의 일부 자릿수를 영단어로 바꾸는 예시입니다.
    1478 → "one4seveneight"
    234567 → "23four5six7"
    10203 → "1zerotwozero3"
    이렇게 숫자의 일부 자릿수가 영단어로 바뀌어졌거나, 혹은 바뀌지 않고 그대로인 문자열 s가 매개변수로 주어집니다. s가 의미하는 원래 숫자를 return 하도록 solution 함수를 완성해주세요.

참고로 각 숫자에 대응되는 영단어는 다음 표와 같습니다.

  • 숫자 영단어
    0 zero
    1 one
    2 two
    3 three
    4 four
    5 five
    6 six
    7 seven
    8 eight
    9 nine
  • 제한사항
    1 ≤ s의 길이 ≤ 50
    s가 "zero" 또는 "0"으로 시작하는 경우는 주어지지 않습니다.
    return 값이 1 이상 2,000,000,000 이하의 정수가 되는 올바른 입력만 s로 주어집니다.

  • 입출력 예
    s result
    "one4seveneight" 1478
    "23four5six7" 234567
    "2three45sixseven" 234567
    "123" 123

📌내풀이

#include <string>

using namespace std;

int solution(string s) {
    int answer = 0;
    string start = ""; //시작하는 알파벳
    for (int i=0;i<s.size();i++)
    {
        if (s[i] == 'o') { //one일 경우
            i += 2;
            start += '1';
        }
        else if (s[i] == 't' && s[i + 1] == 'w') //two일 경우
        {
            i += 2;
            start += '2';
        }
        else if (s[i] == 't' && s[i + 1] == 'h') //thrww일 경우
        {
            i += 4;
            start += '3';
        }
        else if (s[i] == 'f' && s[i + 1] == 'o') //four일 경우
        {
            i += 3;
            start += '4';
        }
        else if (s[i] == 'f' && s[i + 1] == 'i') //five
        {
            i += 3;
            start += '5';
        }

        else if (s[i] == 's' && s[i + 1] == 'i') //six일 경우
        {
            i += 2;
            start += '6';
        }
        else if (s[i] == 's' && s[i + 1] == 'e') //seven일 경우
        {
            i += 4;
            start += '7';
        }
        else if (s[i] == 'e') //eight일 경우
        {
            i += 4;
            start += '8';
        }
        else if (s[i] == 'n') //nine일 경우
        {
            i += 3;
            start += '9';
        }
        else if(isdigit(s[i])) start += s[i]; //숫자일 경우
        else //zero일 경우
        {
            i += 3;
            start += '0';
        }        
    }
    answer = stoi(start);
    return answer;
}

📌다른풀이

#include <algorithm>
#include <string>

using namespace std;

vector<string> numbers = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"};

int solution(string s) {
    int answer = 0;
    for(int i = 0; i < numbers.size(); i++) {
        string word = numbers[i];
        size_t found = s.find(word);
        while (found != npos) 
        {
            s.replace(found, word.length(), to_string(i));
            found = s.find(word, found + 1);
        }
    }
    answer = stoi(s);
    return answer;
}

📍size_t, find()-npos

  • size_t : C++ 표준 라이브러리에서 정의된 부호 없는 정수(unsigned integer) 타입입니다.
  • while (found != npos) : 일반적으로 문자열에서 find() 함수와 함께 사용되며, 문자열 내에서 반복적으로 검색하고자 할 때 유용하다. find() 함수는 찾는 문자열이 발견되지 않은 경우 npos를 반환하므로, 'while (found != npos)'와 함께 사용하면 문자열 내에서 모든 발생을 탐색할 수 있습니다.

✂배울것(regex사용)

#include <regex>

int solution(string s) {
    s = regex_replace(s, regex("zero"), "0");
    s = regex_replace(s, regex("one"), "1");
    s = regex_replace(s, regex("two"), "2");
    s = regex_replace(s, regex("three"), "3");
    s = regex_replace(s, regex("four"), "4");
    s = regex_replace(s, regex("five"), "5");
    s = regex_replace(s, regex("six"), "6");
    s = regex_replace(s, regex("seven"), "7");
    s = regex_replace(s, regex("eight"), "8");
    s = regex_replace(s, regex("nine"), "9");    
    return stoi(s);
}

📍regex()

정규 표현식(Regular Expression, 또는 regex)은 특정 패턴의 문자열을 찾거나 변형하는 데 사용되는 문자열 검색 및 조작 도구입니다. 정규 표현식은 일반적으로 텍스트 처리 작업에서 사용되며, 프로그래밍 언어와 텍스트 편집기 등 다양한 도구에서 지원됩니다.

regex_replace 함수는

  • 첫 번째 인자로 치환할 문자열을 받고,
  • 두 번째 인자로 치환할 패턴을 정규 표현식으로 지정합니다.
  • 세 번째 인자는 치환될 문자열을 나타냅니다.
  • 주의할 점은 regex_replace 함수는 기본적으로 첫 번째 인자인 원본 문자열을 직접 변경하지 않고, 치환된 결과를 반환합니다. 따라서 s에 할당해줘야 기존의 문자열이 치환된 결과로 업데이트됩니다.

📢2. 문자열 내 마음대로 정렬하기

  • 문제 설명
    문자열로 구성된 리스트 strings와, 정수 n이 주어졌을 때, 각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬하려 합니다. 예를 들어 strings가 ["sun", "bed", "car"]이고 n이 1이면 각 단어의 인덱스 1의 문자 "u", "e", "a"로 strings를 정렬합니다.

  • 제한 조건
    strings는 길이 1 이상, 50이하인 배열입니다.
    strings의 원소는 소문자 알파벳으로 이루어져 있습니다.
    strings의 원소는 길이 1 이상, 100이하인 문자열입니다.
    모든 strings의 원소의 길이는 n보다 큽니다.

    인덱스 1의 문자가 같은 문자열이 여럿 일 경우, 사전순으로 앞선 문자열이 앞쪽에 위치합니다.
    -> 다음 인덱스의 문자를 비교하는 것이 아닌, 문자열 자체의 사전순으로 결정한다.

  • 입출력 예
    strings n return
    ["sun", "bed", "car"] 1 [ "car", "bed", "sun" ]
    ["abce", "abcd", "cdx"] 2 ["abcd", "abce", "cdx"]

📌내풀이

#include <string>
#include <vector>
#include <algorithm>

using namespace std;

vector<string> solution(vector<string> strings, int n) {
    vector<string> answer;

    sort(strings.begin(), strings.end(), [n](const string& a, const string& b) {
        if (a[n] == b[n]) {
            return a < b; // 사전순으로 앞선 문자열이 앞쪽에 위치하도록 정렬
        } else {
            return a[n] < b[n];
        }
    });

    for (const auto& str : strings) {
        answer.push_back(str);
    }

    return answer;
}

📍람다 함수

람다 함수(lambda function)는 익명 함수(anonymous function)로서 일시적으로 사용하고자 할 때 유용한 기능입니다. 람다 함수는 함수를 정의하는 동시에 사용할 수 있으며, 주로 간단한 함수나 함수 객체를 생성하는데 활용됩니다.

람다 함수의 기본 구조는 다음과 같습니다:

[캡처](매개변수) { 함수 본문 }

[캡처]: 람다 함수가 외부 변수를 사용할 경우, 해당 변수를 캡처하여 람다 함수 내부에서 사용할 수 있도록 합니다. 캡처는 선택적으로 지정할 수 있으며, 외부 변수를 값으로 복사하거나 참조로 가져올 수 있습니다.
(매개변수): 람다 함수의 매개변수를 선언합니다. 매개변수는 함수 호출 시 전달되는 값을 받는 역할을 합니다.
{ 함수 본문 }: 람다 함수의 동작을 정의하는 함수 본문을 작성합니다. 함수 본문은 중괄호({})로 둘러싸여 있으며, 실행할 코드를 기술합니다.
람다 함수는 주로 함수 객체를 간단하게 생성하고 사용할 때 활용됩니다. 특히, 알고리즘 함수나 컨테이너의 멤버 함수와 함께 사용하여 원하는 동작을 구현할 수 있습니다. 또한, 함수 객체를 인자로 받는 함수에 바로 전달하여 사용할 수 있어 코드의 가독성을 높일 수 있습니다.

📌다른풀이**

#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int i;

bool compare (string a, string b) {
    return a[i] == b[i] ? a < b : a[i] < b[i];
}

vector<string> solution(vector<string> strings, int n) {
    i = n;
    sort (strings.begin(), strings.end(), compare);
    return strings;
}

📍Index별 sort()

compare 함수에 인자 전달을 어떻게 해야할까 고민하다가 결국 노선을 틀었다.
왜 저런 생각을 못했을까
sort()함수 정렬을 설정할때 bool을 통해서 정렬 기준을 바꿔줄 수 있다.
이건 그냥 외우자

profile
성공의 반대는 실패가 아닌 도전하지 않는 것이다.

0개의 댓글