문제
- 백준 1620
1-1. 두 가지 값을 비교해서 가져오려면 List를 2개 만들어서 해야하나?
Map에서 key값과 value값을 같이 받아오면 되지 않을까?
- 백준 11478
1-1. 서로 다른 부분 문자열이 몇개인지 구하려면 총 가능한 부분 문자열을 세고 거기에서 중복되는 값을 빼주면 되려나?
- Assignment 1
3-1. 과제를 다시 확인해보니 중복 주문이 들어갔을 경우 에러가 나는 것을 발견
3-2. 기존 값이 지워져서 안 보이거나 덮어쓰기가 된 것을 확인
시도
- Map에서 entry를 사용해서 key, value 둘 다 가져오도록 해봄
1-1. foreach를 사용
-> foreach는 break가 없다... M 값이 아니라 N값 만큼 받아오게 됨 -> 실패
1-2. Iterator를 사용해서 입력 값과 key값이 같으면 출력하도록
-> value는 받아올 수 있으나 key를 받아오지 못함 -> 실패
1-3. 뭔가 문제를 복잡하게 생각하고 있는 듯 하여 다른 방법을 생각해 봄
- 총 가능한 부분 문자열
2-1. 1개일 때 1개, 2개일 때 3개, 3개일 때 6개, 4개일 때 10개, 5개일 때 15개
-> 전에꺼에 + 기존거하면 되는 거였음. 식으로 표현 : f(n) = f(n-1) + n, f(1) = 1
2-2. 근데 중복되는 값을 빼려고 했는데 일일히 하나하나 집어넣기가 힘들다...
-> 하나하나 만들어서 넣는 Array가 여러개 필요할 것으로 보임...
-> 거기에다가 중복되는지 확인하기 위한 다른 Array도 필요할 듯
-> 하나만 만들어서 하면 안되나?
-> 아예 중복되지 않게 저장하면 되려나?
- 기존 코드에 문제가 있었음
3-1. 중복 되었을 경우 this.food.getFoodName()을 출력하는 것이 아니라 Map에서 값을 가져와야 한다는 것을 인지
3-2. LinkedHashMap을 두개 만들어서 하나는 이름과 갯수를, 하나는 설명과 가격을 가져오도록 하였다.
-> 그런데도 문제 발생
-> 이번에는 기존과는 다르게 이름과 갯수는 잘 들어온 것을 확인했지만, 설명과 가격을 가져오는 LinkedHashMap을 출력할 때 이 부분이 새로 들어온 것으로 덮어쓰여진다는 것을 발견
3-3. int first, second라는 변수를 만들어서 keySet()에 index를 지정하여 first == second 일때 출력되도록 함.
-> 그래도 덮여쓰여지는 문제 발생
해결
- key 값을 따로 저장하도록 하는 String 배열을 만들어서 key값을 저장
1-1. 어차피 배열로 하면 순서대로 저장되기 때문에 상관없다.
1-2. input이 숫자면 value 값을 의미하므로
-> String 배열에 있는 해당 index 번호의 문자열 출력
1-3. input이 숫자가 아니면 key값에서 value를 출력하면됨
1-4. 무리하게 Map이 익숙하지 않은 상태에서 사용했는데 그냥 배열 두개로 했어도 되지 않았을까 싶음...
- Set을 사용하기로 함
2-1. 중복을 허용하지 않고 저장할 수 있도록
2-2. abc면 a, b, c, ab, bc, abc 이렇게 저장되어야 하는데 각각의 길이 별로 따로 저장할 수 있도록 함수를 만들어야 겠다.
2-3. countFunc를 만들어서 매개변수로 저장할 Set, 입력받은 String, 그리고 for문에서의 i를 넘겨줌
-> countFunc의 for문에서 종료 조건을 입력받은 String (input)에서 매개변수로 받은 i의 값을 빼주는 걸로 지정하면 문자열 길이만큼 반복할 수 있겠다.
-> substring(i, i + number - 1) 하면 number에 따라서 문자열의 길이를 조정 가능할 듯
-> 해결
- 문제는 그 보다 위에 map.put과 map.replace에서 있었다.
3-1. map.put 부분을 수정해서 문제가 없을 거라 생각했는데 디버깅을 하니까 linkedhashmap이 사이즈가 달랐다.
3-2. 디버깅을 확인해보니 설명과 가격을 받아오는 linkedhashmap이 계속 한개만 받아오는 것을 확인
-> 메서드를 부모의 get메서드를 쓰고 있었다.....
-> 해결
알게 된 점
- 복잡하게 생각할수록 시간은 더 오래걸리기 마련이다. 능력껏 문제를 풀고, 능력 (지식) 밖에 있는 것을 무리하게 검색해서 사용하려고 하지 말 것
1-1. res.get(key) -> key에 해당하는 map (res) value 값 가져오는 메서드
1-2. res.containsKey(key) -> 해당하는 key값이 map (res) 에 존재하는가 확인하는 메서드
- 따로 함수를 만들어서 사용하는 편이 더 간편하고 깔끔하게 할 수 있음
2-1. input.substring(i, j) -> 해당 String (input)의 부분문자열을 만들 수 있음
-> i번째 인덱스에서 j -1 번째까지 인덱스까지를 포함
- 여러 변수와 메서드를 가지고 있고, 또 코드가 길어서 제대로 확인하지 못했던 거 같다. 시간을 꽤 많이 날렸다...
-> 메서드와 변수를 사용할 때 이름을 제대로 확인하는 습관을 기르자...
오늘 푼 문제
백준 1620 (나는야 포켓몬 마스터) - Java
import java.io.*;
import java.util.*;
public class Main {
// 입력 값이 문자인지 숫자인지 확인하는 함수
public static boolean isInteger(String strValue) {
return strValue.chars().allMatch(Character::isDigit);
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
// 순서가 있게 하기 위해서 LinkedHashMap 사용
Map<String, Integer> res = new LinkedHashMap<>();
// key 값을 따로 저장해서 출력하기 위한 용도
String[]name = new String[N+1];
// 입력 값을 Map과 String 배열에 저장
for(int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
String key = st.nextToken();
int value = i + 1;
res.put(key, value);
name[i] = key;
}
// 입력 값이 숫자면 -> 숫자에 대응되는 키 값 출력
// 입력 값이 문자면 -> 해당 키와 대응되는 value 출력
for (int i = 0; i < M; i++) {
String input = br.readLine();
if (isInteger(input)) bw.write(name[Integer.parseInt(input) - 1] + "\n");
else bw.write(res.get(input) + "\n");
}
bw.flush();
bw.close();
br.close();
}
}
백준 10816 (숫자 카드 2) - Java
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
Map<Integer, Integer> res = new HashMap<>();
st = new StringTokenizer(br.readLine(), " ");
// key 값이 이미 들어가 있다면 해당 value를 + 1 해서 다시 넣어줌
// 없으면 value에 1을 넣어줌
for (int i = 0; i < N; i++) {
int key = Integer.parseInt(st.nextToken());
if (res.containsKey(key)) {
res.put(key, res.get(key) + 1);
}
else {
res.put(key, 1);
}
}
st = new StringTokenizer(br.readLine());
int M = Integer.parseInt(st.nextToken());
st = new StringTokenizer(br.readLine(), " ");
// 해당하는 맵의 키 값이 입력 값과 같으면 key에 해당하는 value 출력
// 아니면 0 출력
for (int i = 0; i < M; i++) {
int number = Integer.parseInt(st.nextToken());
if (res.containsKey(number)) bw.write(res.get(number) + " ");
else bw.write(0 + " ");
}
bw.flush();
bw.close();
br.close();
}
}
백준 1269 (대칭 차집합) - Java
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
Map<Integer, Integer> res = new HashMap<>();
st = new StringTokenizer(br.readLine(), " ");
// 입력 받은 값을 key로 해서 map에 저장
for (int i = 0; i < N; i++) {
int key = Integer.parseInt(st.nextToken());
res.put(key, 1);
}
st = new StringTokenizer(br.readLine(), " ");
// 이미 map에 key값이 있다면 삭제
for (int i = 0; i < M; i++) {
int key = Integer.parseInt(st.nextToken());
if (res.containsKey(key)) {
res.remove(key);
}
else {
res.put(key, 1);
}
}
bw.write(String.valueOf(res.size()));
bw.flush();
bw.close();
br.close();
}
}
백준 11478 (서로 다른 부분 문자열)
import java.io.*;
import java.util.*;
public class Main {
// Set에 값을 add 하기 위한 함수
// 매개 변수로 Set, String, int 값을 받음
// 길이가 1개짜리, 2개짜리 ... input 만큼의 길이를 가진 문자열을 temp로 설정
// -> substring을 사용하여서 temp를 지정해줌
// for 문에 number 값을 집어넣어서 종료 조건을 input.length() - number로 지정
// -> substring 문자열의 길이가 길어질수록 짧아지도록 지정
public static void countFunc (Set<String> res, String input, int number) {
for (int i = 0; i < input.length() - number; i++) {
String temp = input.substring(i, i + number + 1);
res.add(temp);
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String input = br.readLine();
// 중복 허용 안하기 위해서 Set 사용
Set<String> res = new HashSet<>();
// countFunc에서 Set에 값 추가
for (int i = 0; i < input.length(); i++) {
countFunc(res, input, i);
}
bw.write(String.valueOf(res.size()));
bw.flush();
bw.close();
br.close();
}
}