몸과 마음이 건전한 SW 개발자

프로그래머스 [Lv. 3] 매칭 점수 {언어 : Python} [정규식X] 본문

알고리즘/풀었지만 다시 보기

프로그래머스 [Lv. 3] 매칭 점수 {언어 : Python} [정규식X]

스위태니 2024. 8. 27. 17:38

문제 링크

https://school.programmers.co.kr/learn/courses/30/lessons/42893

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

정답 코드

def seperateString(string):
    tmp = ""
    stack = []
    for s in string:
        if "a" <= s <= "z":
            tmp += s
        else:
            if tmp.strip():
                stack.append(tmp)
                tmp = ""
    if tmp.strip():
        stack.append(tmp)
    return stack

def findMetaUrl(pageValue):
    for pv in pageValue:
        if "content=" in pv:
            balance = 0
            tmp = ""
            for p in pv:
                if p == '"':
                    balance += 1
                    if balance == 2:
                        return tmp
                else:
                    if balance == 1:
                        tmp += p
    return ""  

def findAUrl(pageValue):
    for pv in pageValue:
        if "href=" in pv:
            balance = 0
            tmp = ""
            for p in pv:
                if p == '"':
                    balance += 1
                    if balance == 2:
                        return tmp
                else:
                    if balance == 1:
                        tmp += p
    return ""

def solution(word, pages):
    lowerWord = word.lower()
    lenW = len(word)
    links = []
    dictPages = dict()
    cntPages = dict()
    for page in pages:
        pageValues = []
        pageStrings = []
        value = ""
        string = ""
        balance = 0
        cntSameWords = 0
        for p in page.lower().replace("\n", " "):
            if p == "<":
                balance += 1
                value = ""
                if string.strip():
                    pageStrings += seperateString(string)
                string = ""
            elif p == ">":
                balance -= 1
                pageValues.append(value.split(" "))
            else:
                value += p
                if balance == 0:
                    string += p
        currentMeta = ""
        print(pageStrings)
        for pageValue in pageValues:
            how = pageValue[0]
            if how == "meta" and 'property="og:url"' in pageValue:
                tmpString = findMetaUrl(pageValue)
                if tmpString:
                    currentMeta = tmpString
                    links.append(currentMeta)
                    # 0번 인덱스는 기본 점수 1번 인덱스는 외부 링크 개수 2번 인덱스는 
                    if dictPages.get(currentMeta, 0) == 0:
                        dictPages[currentMeta] = []
                    cntPages[currentMeta] = [0, 0]
            elif how == "a":
                tmpString = findAUrl(pageValue)
                if tmpString:
                    cntPages[currentMeta][1] += 1
                    if dictPages.get(tmpString, 0) == 0:
                        dictPages[tmpString] = [currentMeta]
                    else:
                        dictPages[tmpString].append(currentMeta)
        
        for ps in pageStrings:
            if ps == lowerWord:
                cntSameWords += 1
        cntPages[currentMeta][0] = cntSameWords
    
    results = []
    # 링크 점수 = 현재 페이지를 링크한 페이지의 기본 점수 / 외부 링크 개수
    for link in links:
        currentScore = cntPages[link][0]
        if dictPages[link]:
            for atag in dictPages[link]:
                if cntPages[atag][1] > 0:
                    currentScore += cntPages[atag][0] / cntPages[atag][1]
        results.append(currentScore)
    
    maxScore = 0
    answer = 0
    lenR = len(results)
    for i in range(lenR):
        if maxScore < results[i]:
            answer = i
            maxScore = results[i]
    
    return answer

풀이 방법

  1. seperateString 함수
    • 주어진 문자열에서 소문자 알파벳 단어들을 추출한다. HTML 태그나 다른 문자는 무시하고, 알파벳 단어만을 리스트로 반환.
  2. findMetaUrl 함수
    • meta 태그에서 URL을 추출
  3. findAUrl 함수
    • <a> 태그에서 외부 링크 URL을 추출
  4. 초기화
    • lowerWord: 검색어 word를 소문자로 변환한 결과를 저장
    • links: 모든 페이지의 메타 URL을 저장할 리스트
    • dictPages: 각 페이지의 메타 URL을 키로 하고, 해당 페이지에 링크된 다른 페이지의 리스트를 값으로 저장하는 딕셔너리
    • cntPages: 각 페이지의 메타 URL을 키로 하고, [기본 점수, 외부 링크 수]를 값으로 저장하는 딕셔너리
  5. 페이지 분석
    • 각 페이지에 대해 HTML 태그와 텍스트를 분리
    • pageStrings에 텍스트를, pageValues에 태그 내부 값을 저장
    • cntSameWords는 검색어와 일치하는 단어의 수를 세기 위한 변수
  6. HTML 태그와 텍스트 분리
    • HTML 태그가 아닌 부분의 텍스트를 string에 저장하고, 태그가 닫힐 때마다 pageStrings에 단어들을 추가
    • 태그의 내용을 value에 저장하고, 태그가 닫히면 pageValues에 태그 내용을 저장
  7. 메타 URL 및 외부 링크 처리
    • 각 페이지의 메타 URL을 currentMeta에 저장하고, 외부 링크의 URL을 dictPages에 추가
    • cntPages에는 각 페이지의 기본 점수와 외부 링크 수를 저장
  8. 점수를 계산한 뒤 최대 매칭 점수를 가진 페이지의 인덱스를 반환하면 끝!

느낀점

  • 정규식은 모르겠고 노가다로 풀었다.
  • 하지만 정규식을 배워야 할 것 같아서 다음 게시물은 정규식 풀이로 해보겠다.