[Java] String.equals와 "=="에 대해서

Jung In Lee·2024년 4월 11일
0

(1) 펠린드롬?

https://www.acmicpc.net/problem/10942

String.equals()는 두 문자열의 내용이 같은지를 확인하는 함수다.

str[j].equals(str[j + i])

System.out.println(str[1].equals(str[3])); // -> True

"=="는 두 문자열의 주소가 같은지를 확인하는 함수이다.

str[i] == str[i + 1]

System.out.println(str[1] == str[3]); // 0 -> False

이 개념은 문자열 배열을 조건문에 사용할때 실수가 발생할수있다.

특히, 코드가 길어질경우 진짜 못찾는다.

올바른 예)

import java.awt.*;
import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class Main {
    static int N, M;
    static boolean[][] dp;
    static String[] str;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        N = Integer.parseInt(br.readLine()); // 2000

        StringTokenizer st = new StringTokenizer(br.readLine());
        str = new String[N + 1]; // 1 ~ N
        str[0] = "0";
        for (int i = 1; i <= N; i++) {
            str[i] = st.nextToken();
        }

        M = Integer.parseInt(br.readLine()); // 100만개

        dp = new boolean[N + 1][N + 1];

        solve();

        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());
            int start = Integer.parseInt(st.nextToken());
            int end = Integer.parseInt(st.nextToken());

            if (dp[start][end]) {
                bw.write("1\n");
            }
            else{
                bw.write("0\n");
            }
        }

        // 이게 dp지
        //System.out.println(str[1] == str[3]);
        //System.out.println(str[1].equals(str[3]));

        bw.flush();
        bw.close();
        br.close();
    }

    private static void solve() {
        // 1
        for (int i = 1; i <= N; i++) {
            dp[i][i] = true;
        }

        // 2
        for (int i = 1; i <= N - 1; i++) {
            if (str[i].equals(str[i + 1])) dp[i][i + 1] = true;
        }

        // 3
        for (int i = 2; i < N; i++) { // i + 1 ~ n 길이 (인덱스 기준)
            for (int j = 1; j <= (N - i); j++) { // 길이에따른 범위
                // 처음 == 끝 (양 끝점 비교)
                // 처음 + 1 ~ == 끝 - 1 ~ (저장된 dp 사용)
                if (str[j].equals(str[j + i]) && dp[(j) + 1][(j + i) - 1]) {
                    dp[j][j + i] = true;
                }
            }
        }
    }
}

잘못된 예)

import java.awt.*;
import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class Main {
    static int N, M;
    static boolean[][] dp;
    static String[] str;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        N = Integer.parseInt(br.readLine()); // 2000

        StringTokenizer st = new StringTokenizer(br.readLine());
        str = new String[N + 1]; // 1 ~ N
        str[0] = "0";
        for (int i = 1; i <= N; i++) {
            str[i] = st.nextToken();
        }

        M = Integer.parseInt(br.readLine()); // 100만개

        dp = new boolean[N + 1][N + 1];

        solve();

        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());
            int start = Integer.parseInt(st.nextToken());
            int end = Integer.parseInt(st.nextToken());

            if (dp[start][end]) {
                bw.write("1\n");
            }
            else{
                bw.write("0\n");
            }
        }

        // 이게 dp지
        //System.out.println(str[1] == str[3]);
        //System.out.println(str[1].equals(str[3]));

        bw.flush();
        bw.close();
        br.close();
    }

    private static void solve() {
        // 1
        for (int i = 1; i <= N; i++) {
            dp[i][i] = true;
        }

        // 2
        for (int i = 1; i <= N - 1; i++) {
            if (str[i] == str[i + 1]) dp[i][i + 1] = true;
        }

        // 3
        for (int i = 2; i < N; i++) { // i + 1 ~ n 길이 (인덱스 기준)
            for (int j = 1; j <= N - i; j++) { // 길이에따른 범위
                // 처음 == 끝 (양 끝점 비교)
                // 처음 + 1 ~ == 끝 - 1 ~ (저장된 dp 사용)
                if (str[j] == str[j + i] && dp[j + 1][j + i - 1]) {
                    dp[j][j + i] = true;
                }
            }
        }
    }
}

두 코드를 돌려보면 틀린 답이 나온다.
1) 답

1
0
1
1

2) 답

0
0
1
0

문제는 답이 맞았을때다.
아래 조건문중 하나만 이렇게 바꿔보자.

		// 2
        for (int i = 1; i <= N - 1; i++) {
            if (str[i] == str[i + 1]) dp[i][i + 1] = true;
        }

        // 3
        for (int i = 2; i < N; i++) { // i + 1 ~ n 길이 (인덱스 기준)
            for (int j = 1; j <= N - i; j++) { // 길이에따른 범위
                // 처음 == 끝 (양 끝점 비교)
                // 처음 + 1 ~ == 끝 - 1 ~ (저장된 dp 사용)
                if (str[j].equals(str[j + i]) && dp[j + 1][j + i - 1]) {
                    dp[j][j + i] = true;
                }
            }
        }

차이점을 찾을 수 있겠는가?

이 코드는 심지어 답이 맞았는데도 oj에 돌려보면 틀렸습니다가 나온다. 이런경우 답찾기가 난감해진다.

결론은 뭐... 알고 쓰자이다.

읽어보면 좋은 블로그

https://coding-factory.tistory.com/536

profile
Spring Backend Developer

0개의 댓글