トーン
しょかい
「{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()パラメータとしての正規表現には、「{」、「{」を含めることができる.
これを一般化すると、
正規表現として表示する場合は、次のように表示できます.(文字間のスペースは無視)
"( [ { } ] , ? [ { } ] )"
指定された文字列では、始点は常に{{{であるため、()を分割すると正規表現になります.
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);
}
Reference
この問題について(トーン), 我々は、より多くの情報をここで見つけました
https://velog.io/@nelljun/튜플
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
String[] splitStrArr = s.substring(2).split(",|([{}],?[{}])");
上の解答で使われている正規表現も実は作りにくいので、簡単な方法があるのか悩んでいます.
最初から大かっこをそのまま外して、小かっこが見えてきました.
いずれにしても答えを得るには数字文字列が必要なので、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);
}
Reference
この問題について(トーン), 我々は、より多くの情報をここで見つけました https://velog.io/@nelljun/튜플テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol