アルファベット順にソートされたarraylistを5セットに分割する必要があります。Javaを使用 - AとEの間 - FとJの間の単語のリストを含むセット2 - KとOの間の単語のリストを含むセット3 - UとUの間の単語のリストを含むセット5とZは、(AからEへ、FからJへ、AからEへ、FからJへ...)
私はそれを行う効率的な方法を教えてもらえますか?私は8
おかげで、 Tushar
アルファベット順にソートされたarraylistを5セットに分割する必要があります。Javaを使用 - AとEの間 - FとJの間の単語のリストを含むセット2 - KとOの間の単語のリストを含むセット3 - UとUの間の単語のリストを含むセット5とZは、(AからEへ、FからJへ、AからEへ、FからJへ...)
私はそれを行う効率的な方法を教えてもらえますか?私は8
おかげで、 Tushar
あなたはすべての要素が最もパフォーマンス効率的方法はbinarySearch()
とsubList()
を使用するときに、簡単な大文字(すなわち、A-Z)で開始するを保証されてソートされたリストで始まる場合。
パフォーマンスは、binarySearch()
からO(log n)です。
List<String> list = Arrays.asList("Actually", "Chalk", "Dramatic", "Fence", "Horrible", "Labored",
"Resonant", "Six", "Slap", "Spark", "Tin", "Treatment");
int idxF = Collections.binarySearch(list, "F");
int idxK = Collections.binarySearch(list, "K");
int idxP = Collections.binarySearch(list, "P");
int idxU = Collections.binarySearch(list, "U");
if (idxF < 0) idxF = ~idxF;
if (idxK < 0) idxK = ~idxK;
if (idxP < 0) idxP = ~idxP;
if (idxU < 0) idxU = ~idxU;
List<String> listA_E = list.subList(0, idxF);
List<String> listF_J = list.subList(idxF, idxK);
List<String> listK_O = list.subList(idxK, idxP);
List<String> listP_T = list.subList(idxP, idxU);
List<String> listU_Z = list.subList(idxU, list.size());
System.out.println(listA_E);
System.out.println(listF_J);
System.out.println(listK_O);
System.out.println(listP_T);
System.out.println(listU_Z);
出力
[Actually, Chalk, Dramatic]
[Fence, Horrible]
[Labored]
[Resonant, Six, Slap, Spark, Tin, Treatment]
[]
あなたがソートされていないリストで起動した場合、これを行うための最も効率的な方法は、Group
がグループを代表するユニークな値であるMap<Group, List<String>>
を作成することです。グループの最初の文字(A
、F
、K
、P
、U
)の単純なCharacter
でもかまわない。 enum
。
パフォーマンスは、TreeMap
/TreeSet
建物からのO(n log n)です。
enum LetterGroup {
A_E, F_J, K_O, P_T, U_Z;
public static LetterGroup of(String s) {
char ch = Character.toUpperCase(s.charAt(0));
if (ch >= 'A' && ch <= 'E') return A_E;
if (ch >= 'F' && ch <= 'J') return F_J;
if (ch >= 'K' && ch <= 'O') return K_O;
if (ch >= 'P' && ch <= 'T') return P_T;
if (ch >= 'U' && ch <= 'Z') return U_Z;
throw new IllegalArgumentException(s);
}
}
このような列挙型は、Java 8 Streamsを使用して実行できます。
List<String> list = Arrays.asList("dramatic","slap","chalk","fence","resonant","tin",
"six","labored","spark","treatment","horrible","actually");
Map<LetterGroup, Set<String>> groups = list.stream()
.collect(Collectors.groupingBy(LetterGroup::of,
TreeMap::new,
Collectors.toCollection(TreeSet::new)));
for (Entry<LetterGroup, Set<String>> entry : groups.entrySet())
System.out.println(entry);
出力も非ソートされたリストのために働く
A_E=[actually, chalk, dramatic]
F_J=[fence, horrible]
K_O=[labored]
P_T=[resonant, six, slap, spark, tin, treatment]
あなたは修飾子機能と列挙型などのいくつかの種類を必要とするJavaを使用しています(擬似コード):
enum Scope{AE, FJ, //...
static Scope inScope(String s){
return Arrays.asStream(Scope.values())
.stream().filter(s -> isInScope(s)).findFirst().get();
}
abstract boolean isInScope(String word);
}
Function<String, Scope> f = Scope::inScope;
// in code
listOfWords.stream().groupBy(f).values();
Scope
列挙は文字でグループを定義します。メソッドisInScope
では、範囲内の単語が指定されているかどうかをチェックします。機能f
は単なるショートカットです。最後の行は、単語をスコープでグループ化し、Map<Scope, List<String>>
と値を抽出する操作です。
一般的な考え方は、標準APIにgroupBy
コレクタがあることです。それらは分類器機能を必要とする。その関数は、私の例のように、if、またはenumの束である可能性があります。
最も簡単な解決策はある
Map<Integer, List<String>> m = list.stream()
.collect(Collectors.groupingBy(s->Math.min((s.charAt(0)-'A'&~32)/5,4)));
// the keys range from 0 to 4, as can be shown with:
System.out.println("a-e: "+m.getOrDefault(0, Collections.emptyList()));
System.out.println("f-j: "+m.getOrDefault(1, Collections.emptyList()));
System.out.println("k-o: "+m.getOrDefault(2, Collections.emptyList()));
System.out.println("p-t: "+m.getOrDefault(3, Collections.emptyList()));
System.out.println("u-z: "+m.getOrDefault(4, Collections.emptyList()));
あなたは5つのコレクションを運ぶのではなく、マップを使用することを検討している場合later-あなたはきれいなプリントキーを代わりに使うことができます:
String[] key={"a-e", "f-j", "k-o", "p-t", "u-z" };
Map<String, List<String>> m = list.stream()
.collect(Collectors.groupingBy(s->key[Math.min((s.charAt(0)-'A'&~32)/5,4)]));
for(String k:key) System.out.println(k+": "+m.getOrDefault(k, Collections.emptyList()));
もちろん、このコードはソートされたリストでも機能しますが、ソートされた性質は利用されません。効率のためにソートされた性質を利用するには、Andreas’ answerに示すように、バイナリ検索または同様の手法を使用する必要があります。もちろん、それは単一のgroupingBy
操作よりもコードの方が少し複雑です...
パイプラインは1つのコレクションにしか収集できません。マップ>に保存しないでください。 –
すべての単語が大文字であると想定できますか? – Kelvin