ALGORITHM NOTE1

BOJ 14425 - 문자열 집합

집합들 집합!

#algorithm#boj#silver#data-structures#hash-set#string
아카이브로 돌아가기

문제 링크

문제

총 N개의 문자열로 이루어진 집합 S가 주어진다.

입력으로 주어지는 M개의 문자열 중에서 집합 S에 포함되어 있는 것이 총 몇 개인지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 문자열의 개수 N과 M (1 ≤ N ≤ 10,000, 1 ≤ M ≤ 10,000)이 주어진다.

다음 N개의 줄에는 집합 S에 포함되어 있는 문자열들이 주어진다.

다음 M개의 줄에는 검사해야 하는 문자열들이 주어진다.

입력으로 주어지는 문자열은 알파벳 소문자로만 이루어져 있으며, 길이는 500을 넘지 않는다. 집합 S에 같은 문자열이 여러 번 주어지는 경우는 없다.

출력

첫째 줄에 M개의 문자열 중에 총 몇 개가 집합 S에 포함되어 있는지 출력한다.

풀이

집합 S 안에 특정 문자열이 들어 있는지만 여러 번 확인하는 문제라서, 입력된 문자열들을 집합 자료구조에 넣어 두고 질의 문자열마다 포함 여부를 검사하면 된다. 문자열을 매번 선형 탐색하면 입력 크기에서 손해가 크다.

코드는 S를 저장한 뒤 M개의 질의를 읽으며 집합에 있는 경우만 카운트를 올린다. membership query를 빠르게 만드는 자료구조 선택이 곧 풀이의 핵심이다.

코드

cpp
#include <iostream>
#include <set>
using namespace std;
 
void solve() {
 
	int n, m, cnt = 0;
	cin >> n >> m;
 
	string s;
	set<string> str;
 
	for (int i = 0; i < n; i++) {
		cin >> s;
		str.insert(s);
	}
 
	for (int j = 0; j < m; j++) {
		cin >> s;
		
		if (str.find(s) != str.end())
			cnt++;
	}
 
	cout << cnt << '\n';
}
 
int main() {
    
    ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
    
	solve();
 
    return 0;
}

복잡도

  • 시간 복잡도: set 삽입과 조회가 각각 O(logN)O(\log N)이므로 전체 시간 복잡도는 O((N+M)logN)O((N + M) \log N)이다.
  • 공간 복잡도: 기준 문자열 집합을 저장하므로 O(N)O(N)이다.

마무리

기준 문자열을 집합에 넣어 두면 각 질의는 포함 여부 확인으로 바뀐다. 선형 탐색을 피하는 자료구조 선택이 이 문제의 핵심이다.