파일 정리
문제 살펴보기
문제 요약
파일을 확장자 별로 정리해서 개수를 정리합니다. 이것을 확장자 기준 사전 순으로 오름차순 정렬하여 출력합니다.
확장자는 . 을 사용하므로 그걸 쪼개서 이름과 개수(빈도)를 알파벳 순서대로 출력하면 되는 문제입니다.
전략
- 기존에 잘 알려진 HashMap을 사용해볼 수 있습니다. 다만 알파벳 순서대로 차후에 sort 작업을 수행해야 합니다.
- 새롭게 등장한 TreeMap 을 사용해본다. 자동으로 알파벳 순서대로 정렬해주므로 편리합니다.
공통 사항
- Java로 백준에 제출할 때에는 Main 으로 클래스 이름을 지정해야 합니다.
- 입력은 Scanner 객체 sc로 받습니다.
- 숫자와 문자가 동시에 입력받아야 한다면, 두가지 전략이 있습니다.
- 숫자는 sc.nextInt() 로 받고, sc.nextLine() 으로 줄바꿈을 입력받고 그 다음에 문자열인 sc.nextLine을 입력받아야 정상적으로 숫자와 문자열이 입력됩니다.
- 숫자든 문자열이든 모조리 sc.nextLine() 으로 입력받고, 차후에 숫자형으로 변환(parseInt, Integer.valueOf)을 수행하여 활용합니다.
HashMap
- 숫자 입력받고, 해당 숫자의 길이만큼 파일명을 담아줄 문자열 객체를 생성하고, 확장자명과 개수를 입력받을 Map 객체 생성하기.
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
// 구분을 위한 줄바꿈 처리
sc.nextLine();
String[] fileArr = new String[N];
Map<String, Integer> fileMap = new HashMap<>();
2. 문자열도 입력받아서 위에서 만든 fileArr 배열에 입력하고, map에 입력할 때 mapKey를 생성해서 파일명에서 . 을 기준으로 분할합니다.
...
for(int i = 0; i < fileArr.length; i++){
fileArr[i] = sc.nextLine();
...
}
3. 이를 containsKey 메서드를 통해 기존의 키값에 포함한다면 해당 키에 value 값만 1씩 증가시킵니다. 빈도수는 value가 되니 이걸 재귀적으로 입력해야 안전하게 map에 입력이 됩니다.
for(int i = 0; i < fileArr.length; i++){
fileArr[i] = sc.nextLine();
String mapKey = fileArr[i].split("[.]")[1];
if(fileMap.containsKey(mapKey)){
fileMap.put(mapKey, fileMap.get(mapKey) + 1);
} else {
fileMap.put(mapKey, 1);
}
}
결과는 아래와 같습니다.
8
sbrus.txt
spc.spc
acm.icpc
korea.icpc
sample.txt
hello.world
sogang.spc
example.txt
이 map에 담긴 값을 출력해서 살펴보면 다음과 같습니다.
{txt=3, world=1, spc=2, icpc=2}
이 값을 보면 txt부터 랜덤하게 출력됩니다. 이 순서를 교정하기 위해 Collections.sort() 를 사용해보겠습니다.
컬렉션 형태 중에서 List<String>을 사용해서 구현해봤습니다.
keySet이라는 리스트를 만들고, 그 안에 생성할 때부터 key 값의 집합인 keySet()
메서드로 맵에 있는 키값만 모아둔것을 파라미터로 전달합니다.
Collections.sort() : 컬렉션 내 요소를 오름차순으로 정렬해줍니다.
List<String> keySet = new ArrayList<>(fileMap.keySet());
// 키 값으로 오름차순 정렬
Collections.sort(keySet);
for(String key : keySet){
System.out.println(key + " " + fileMap.get(key));
}
출력하면 다음과 같습니다.
icpc 2
spc 2
txt 3
world 1
내림차순은, Collections.sort(리스트, Collections.reverseOrder()) 사용합니다.
// 키 값으로 오름차순 정렬
Collections.sort(keySet, Collections.reverseOrder());
System.out.println(keySet);
for(String key : keySet){
System.out.println(key + " " + fileMap.get(key));
}
출력하면, 다음과 같습니다.
world 1
txt 3
spc 2
icpc 2
이번에는 배열 객체를 통해 정렬합니다.
Object[] keyArr = fileMap.keySet().toArray();
Arrays.sort(keyArr);
// 이 경우 정렬된 것이 배열로 만들어 졌으니 그대로 이걸 사용해서 for문으로 출력함.
for(int i = 0; i < keyArr.length; i++){
System.out.println(keyArr[i] + " " + fileMap.get(keyArr[i]));
}
위 방법은 List 객체 대신에 toArray() 메서드를 통해 배열 객체를 만드는 것입니다.
배열 객체를 Object 타입으로 만들고, 그리고 Arrays.sort() 메서드로 정렬한 다음 for 문으로 바로 그 배열을 출력하면 됩니다.
TreeMap
트리맵의 가장 큰 특징이, 입력된 키를 자동으로 오름차순으로 정렬해준다는 점입니다.
코드 살펴보기
처음에 TreeMap() 으로 선언합니다. 나머지 과정은 HashMap과 동일하게 수행하되, 별도의 정렬 작업 없이 바로 출력합니다.
Map<String, Integer> fileMap = new TreeMap<String, Integer>();
for(int i = 0; i < fileArr.length; i++){
fileArr[i] = sc.nextLine();
String mapKey = fileArr[i].split("[.]")[1];
if(fileMap.containsKey(mapKey)){
fileMap.put(mapKey, fileMap.get(mapKey) + 1);
} else {
fileMap.put(mapKey, 1);
}
}
// 향상된 for문을 활용해서 출력.
for(String key : fileMap.keySet()){
// 문자열을 연결한다.
System.out.println(key + " " + fileMap.get(key));
}
출력하면 위와 동일하게 나타납니다. 간단하죠?
world 1
txt 3
spc 2
icpc 2
'코딩테스트 준비' 카테고리의 다른 글
공백없는 문자열 입력받아 출력하기 / 더 긴 문자열 (0) | 2024.10.18 |
---|---|
[Python] 오늘의 코딩 문제: 문자열 (1) | 2023.12.15 |
[PCCP 모의고사 1회] 1. 외톨이 알파벳 (0) | 2023.12.11 |
[Java] 럭키 스트레이트 (0) | 2023.06.01 |
[Java] 서울에서 김서방 찾기 (0) | 2023.04.18 |