トーン



しょかい


「{1,2,3},{2,1},{1,2,4,3}および{2}」ではsplit(regex)を使用して各{}グループを要素とするString[]を作成します.
(1番目の要素:「1,2,3」2番目の要素:「2,1」3番目の要素:「1,2,4,3」)
split()パラメータとしての正規表現には、「{」、「{」を含めることができる.
これを一般化すると、
  • {or}そのうちの1つは
  • {or}そのうちの1つは
  • この1 2 3は1つの組み合わせで大丈夫です
    正規表現として表示する場合は、次のように表示できます.(文字間のスペースは無視)
    "( [ { } ] , ? [ { } ] )"
    指定された文字列では、始点は常に{{{であるため、()を分割すると正規表現になります.
    String[]の最初の要素は常に空の文字列です.
    削除するには、前の2つの文字列を切り取ってsplit()を呼び出します.(s.substring(2))
    String[] strSplit = s.substring(2).split("([{}],?[{}])");
    「1,2」文字列を再分割し、配列内の各文字列を配列に再変換します.
    String[][] finalSplit = new String[strSplit.length][];
    
    for(int i=0; i<strSplit.length; i++) {
        finalSplit[i] = strSplit[i].split(",");
    }//for end
    問題で解く必要がある例の要素の順序は、その要素が出現する回数が多い順序であるため、String[]]の要素をそれぞれ探索する際に、各要素の数字(ここではString処理)をキーとし、その要素が出現した回数(map.getOrDefault()をvalueとしてmapに値を格納する.
    Map<String, Integer> map = new HashMap<>();
    
    for(int i=0; i<finalSplit.length; i++) {
        for (String str : finalSplit[i]) {
        	//현재 map에 str을 key로 하는 value값이 있다면 가져오고,
            //없다면 디폴드 값(0)을 가져와 1을 더하면 해당 원소가 나온 횟수가 된다.
            map.put(str, map.getOrDefault(str, 0)+1);
        }
    }//for end
    mapをvalueで降順に並べ替えます.
    Collections.sort()を利用するために、MapのEntryを要素とするリストを作成します.
    Comparatorクラスの匿名オブジェクトをsort()のパラメータに渡します.
    List<Entry<String, Integer>> entries = new LinkedList<>(map.entrySet());
    
    Collections.sort(entries, new Comparator<Entry<String, Integer>>() {
        @Override
        public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
       	//내림차순 정렬
            return o2.getValue()-o1.getValue();
        }
    });
    値の昇順に並べられたリスト内の各要素(Entry)に、キー値を順番に返す正解配列の要素として挿入します.
    int[] answer = new int[entries.size()];
    
    for(int i=0; i<answer.length; i++) {
        answer[i] = Integer.parseInt(entries.get(i).getKey());
    }
     return answer;

    改善された解答1


    どうせ漏れた元素の数だけでいいので、
    String[]の各要素を要素単位に一度に分割するには、正規表現を変更します.
    最初の解としての正規表現「1,2,3」「2,1」...文字列は区切ります.OR条件に「,」が含まれている場合は、「1」「2」「3」「2」「1」…区切り文字列を使用できます.
    ", | ( [ { } ] , ? [ { } ] )"
    前に追加しました.これにより、各要素を要素とするString[]を一度にsplit()で作成できます.
    String[] splitStrArr = s.substring(2).split(",|([{}],?[{}])");

    改善された解答2


    上の解答で使われている正規表現も実は作りにくいので、簡単な方法があるのか悩んでいます.
    最初から大かっこをそのまま外して、小かっこが見えてきました.
    いずれにしても答えを得るには数字文字列が必要なので、All()をカッコで置き換えて空の文字列に変換します.
    String newStr = s.replaceAll("[{}]", "");
    "{{1,2,3},{2,1},{1,2,4,3},{2}}" -> "1,2,3,2,1,1,2,4,3,2"
    文字列は上記のように簡単になるので、複雑な正規表現を必要とせずに文字列を1つの文字列に分けることができます.
    String[] splitStrArr = newStr.split(",");
    上の図と同様に、Mapに<要素、要素が現れる回数>の値を入力します.
    ここに4つの要素がある場合、
    tupleの前の要素の出現回数は4回->正解配列の0番目のindex
    2番目の要素は3番目->答え配列1番目のindex
    3番目の要素は2番目->答え配列2番目のindex
    4番目の要素は1->答え配列3番目のindexです
    これらの規則を用いて,Mapのvalue値に直接基づいて降順ソートするのではなく,value値で正解配列を解くindexを代入する.
    int size = map.size();
    int[] answer = new int[size];
    
    for (String key : map.keySet()) {
        answer[size-map.get(key)] = Integer.parseInt(key);
    }