AlgoCpper / Algorithms

0 stars 4 forks source link

[240426] BOJ 20920 영단어 암기는 괴로워 - 어디에서 segfault가 발생할까요? #98

Closed cherry-go-round closed 5 months ago

cherry-go-round commented 6 months ago
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));
        String input = br.readLine();
        String[] split = input.split(" ");

        int n = Integer.parseInt(split[0]);
        int m = Integer.parseInt(split[1]);

        Map<String, Integer> map = new HashMap<>();

        for (int i = 0; i < n; i++) {
            String s = br.readLine();
            if (s.length() < m) continue;

            if (!map.containsKey(s)) {
                map.put(s, 1);
            } else {
                map.put(s, map.get(s) + 1);
            }
        }

        List<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());

        list.sort((e1, e2) -> {
            if (!Objects.equals(e1.getValue(), e2.getValue())) return e2.getValue() - e1.getValue();
            if (e1.getKey().length() != e2.getKey().length()) return e2.getKey().length() - e1.getKey().length();
            return e1.getKey().compareTo(e2.getKey());
        });

        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        for (Map.Entry<String, Integer> entry : list) {
            bw.write(entry.getKey() + "\n");
        }

        bw.flush();
    }
}

자바로 통과한 코드입니다.

#include <bits/stdc++.h>
using namespace std;

int n, m;
unordered_map<string, int> wordMap;

int compare(pair<string, int> &p1, pair<string, int> &p2) {

    if (p1.second != p2.second) return p2.second - p1.second;

    if (p1.first.length() != p2.first.length()) return p1.first.length() - p2.first.length();

    return p1.first < p2.first;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);

    cin >> n >> m;

    while(n--) {
        string s;
        cin >> s;
        if (s.length() < m) continue;

        if (wordMap.find(s) == wordMap.end()) {
            wordMap.insert({ s, 1 });
        } else {
            wordMap[s]++;
        }
    }

    vector<pair<string, int>> v;

    for (auto p : wordMap) {
        v.push_back(p);
    }

    sort(v.begin(), v.end(), compare);

    for (auto p : v) {
        cout << p.first << '\n';
    }
}

원래 C++코드입니다. 어떤 부분이 잘못되었을까요? 테스트케이스 중 일부는 통과하는데 진행 중에 segfault가 발생합니다.

githublees commented 5 months ago

bool compare(pair<string, int> &p1, pair<string, int> &p2) {

if (p1.second != p2.second) return p1.second > p2.second;

if (p1.first.length() != p2.first.length()) return p1.first.length() > p2.first.length();

return p1.first < p2.first;

}

compare 함수 조건문을 어떻게 설정하냐에 따라 문제가 발생하는거 같아요

비교연산자 쓰니까 segfault가 덜 나오기는 하는데 가끔 터지는 segfault는 왜 그런지는 모르겠네요..ㅠ

cherry-go-round commented 5 months ago
sort(
        v.begin(),
        v.end(),
        [&](pair<string, int> p1, pair<string, int> p2) {

                if (p1.second != p2.second) return p1.second > p2.second;

                if (p1.first.length() != p2.first.length()) return p1.first.length() > p2.first.length();

                return p1.first < p2.first;
            }
    );

이렇게 적으니까 통과됐습니다! bool 함수를 전달했어야 했네요. 아마 0이나 1이 나와야 하는 상황에서 다른 값이 나오니까 문제가 되었던 것 같아요. 그런데 동작이 잘못되는 것은 이해가 되는데 왜 segmentation fault인지는 잘 모르겠네요.😅