# 6. 매칭 점수(문자열 파싱)

핵심

* indexOf()활용
* 알파벳 판단 : Character.isLetter(char c)
* 특이 for문 : for(int start = posL; ;) { start = s.indexOf(word,start+1); ...}\
  \=> start위치에서 검색어 탐색을 시작하며, start는 1씩 증가(오른쪽으로 1칸씩 이동)

**구해야하는 것**\
**각 페이지당**

1. **기본 점수**
2. **외부 링크 수**
3. **⭐️ 링크 점수 => 각 페이지마다 문자열 파싱 후에 a태그 url 추출함으로써 도출 가능!**
4. **매칭 점수 = 1 + 3**

0\. 준비 단계\
대소문자 구분하지 않기 때문에 연산 용이하게 하기 위해 소문자로 변환.\
검색어의 크기 저장.\
Map과 List 생성 & 초기화.

1. meta태그 찾아서 url 찾아 저장 : pges\[i] 마다 url 구한다.\
   a 태그에서 외부 링크 페이지의 링크 점수 계산하기 위해 \<url,idx>로 Map 구성
2. 기본점수(검색어카운팅) : body 태그 찾아서 검색어 카운팅\
   문제에서 "알파벳 제외한 다른 모든 문자로 구분한다" 고 되어 있기 때문에 검색어 시작과 끝은 알파벳이면 안 된다.\
   \=> Character.isLetter()로 판단한다!
3. 외부 링크 갯수 카운팅 : a태그 찾아서 세면 됨.
4. 매칭 점수 완성\
   **문자열 파싱이 끝난 후 다시 pages 배열 순회**하면서 **각 페이지에 a태그에 포함된 외부 링크 url 추출**하여 **Map에서 찾고, Map에 존재한다면 그 페이지의 매칭점수를 완성**한다.\
   ① a 태그 찾기\
   ② 외부 링크 url 시작, 끝 위치 찾기 (url 추출)\
   ③ url(=key)로 Map에서 idx(=value) 찾기\
   ④ 3에서 찾은 인덱스(idx)로 해당 페이지의 매칭 점수 score을 완성한다.\
   &#x20;  앞서 구한 score 기본 점수로 되어있기 때문에 링크 점수 구해서 score에 더해주면 매칭 점수 완성.\
   pageList.get(idx).score += (double)pageList.get(idx).basic / pageList.get(idx).link;\
   ⑤ 새로 정의한 정렬 기준 Comp로 List 컬렉션 pageList 정렬\
   &#x20; score이 같으면 인덱스 작은 것부터 오름차순 정렬\
   &#x20; socre은 높은 순서대로 내림차순 정렬\
   ⑥ 컬렉션의 첫번째 요소(page클래스)의 idx 값을 리턴 : 정답

3번째 풀었을 때 잘한 부분

① url 찾을 때 : meta 태그 시작(posL), 끝(posR) 먼저 찾은 이 위치들을 연쇄적으로 이용해서 url의 시작(mid), 끝(posR) 위치를 찾고, substring으로 url을 추출할 수 있다!\
② 기본점수 구할 때 : body태그 위치(posL)를 먼저 찾은 후, 검색어를 탐색한다. 이 posL을 이용하여 특이 for문에서 posL에서 시작해 이용하여 오른쪽으로 1씩 증가시켜가면서 검색어를 탐색한다!\
검색어가 존재하지 않는다면 indexOf는 -1을 리턴. 리턴값이 -1이면 탐색을 종료.\
⭐️검색어 단위는 알파벳이 아닌 모든 문자들로 구분된다고 했기 때문에 검색어 위치 start를 찾았다면 검색어 전과 후 start-1, start+wsize는 알파벳이 아니여야한다. => Character.isLetter(char c)로 조건 판단 가능!\
③ 외부 링크수 : 마찬가지로, ②에서 구한 body태그 시작 위치를 활용하여 a태그 갯수를 구한다.\
a태그가 존재하지 않는다면 indexOf는 -1을 리턴. 리턴값이 -1이면 탐색을 종료.\
④ 매칭 점수 구할 때\
\=>①②③④ 모두 태그를 먼저 찾은 다음 url 또는 검색어 등을 찾아야하는데 이때, **태그의 시작 위치와 끝 위치를 먼저 찾은 다음**, 이 위치들을  **진짜 찾고자하는 것**을 것의 **탐색 위치(indexOf의 2번째 파라미터;탐색을 시작하는 위치)로 사용**할 수 있다!

특히 마지막에 매칭 점수를 구할 때, 각 페이지마다 a태그를 탐색한 후, url을 탐색해야한다. 이 때, for(int posL=0,posR=0; ;)으로 반복문을 구성해서 a 태그 시작 위치를 먼저 찾는다. a태그가 존재하지 않는다면 탐색 반복문을 종료한다!

**a태그 시작 위치를 찾아서 posL**에 저장하고, 이어서 **url의 시작, 끝 위치**를 저장해야하기 때문에 **posL과 posR에 각각 url의 시작, 끝 위치를 저장**한다!

**url을 찾아서 Map에서 해당 페이지의 인덱스를 조회**한다!!

```java
for(int i=0;i<pages.length;i++){
            String s = pages[i];
            //int start = s.indexOf("<a href",posL);
            for(int posL=0,posR=0; ;){//반복 조건? 언제 탈출하지?
                //a태그 먼저 찾음.
                posL = s.indexOf("<a href",posL+1);
                if(posL == -1) break;//없는 경우 리턴해야함! 생각만하고 구현X
                
                posL = s.indexOf("https://",posL);
                posR = s.indexOf("\"",posL);
                String linkurl = s.substring(posL,posR);//큰따옴표 다음부터 큰따옴표 전까지
                
                Integer index = pageMap.get(linkurl);//a태그의 링크의 인덱스를 찾아낸다!
                if(index != null){
                    pageList.get(index).score += (double)pageList.get(i).basic / pageList.get(i).link;
                }
            }
            
        }
```

**특이한 for문 - 대표적인 예) 검색어 탐색⭐️⭐️⭐️⭐️⭐️**

for(int start = posL; ; ) {\
&#x20; start = s.indexOf(word,start+1); //start위치에서 탐색을 시작하고, start는 오른쪽으로 1씩 증가.
