まず、希望するかもしれない示し2つのフィールドを含むコンテナオブジェクトを使用してデータ構造を単一の配列に変更します。このコンテナオブジェクトは、Comparableインタフェースを実装します。
しかし、あなたの言うことに固執、1つのアプローチは次のようになります。
/**
* Sorts parallel arrays in-place. Sorted by the first array and updating
* all other arrays to match.
* Uses the natural sorting of the objects.
* All arrays must be the same length.
*
* @param keys the values used to sort, may be duplicate
*
* @param otherArrays the arrays to have reordered to match the sorting of
* the keys array.
*
* @exception IllegalArgumentException if any of otherArrays have a length
* different that the keys array.
*/
public static <E extends Comparable<? super E>> void sortParallelArrays(
E[] keys,
Object[] ... otherArrays
) {
int numKeys = keys.length;
int numOtherArrays = otherArrays.length;
for(Object[] otherArray : otherArrays) {
if(otherArray.length != numKeys) {
throw new IllegalArgumentException("Mismatched array lengths");
}
}
// A list of all indexes per key
// This also does the sorting within the TreeMap using natural ordering
SortedMap<E, List<Integer>> originalIndexesByKey = new TreeMap<E, List<Integer>>();
// Populate the map
for(int i = 0; i < numKeys; i++) {
E key = keys[i];
List<Integer> originalIndexes = originalIndexesByKey.get(key);
if(originalIndexes == null) {
// Optimization for the non-duplicate keys
originalIndexesByKey.put(key, Collections.singletonList(i));
} else {
if(originalIndexes.size() == 1) {
// Upgrade to ArrayList now that know have duplicate keys
originalIndexes = new ArrayList<Integer>(originalIndexes);
originalIndexesByKey.put(key, originalIndexes);
}
originalIndexes.add(i);
}
}
// Store back to keys and sort other arrays in a single traversal
Object[][] sortedOtherArrays = new Object[numOtherArrays][numKeys];
int pos = 0;
for(Map.Entry<E, List<Integer>> entry : originalIndexesByKey.entrySet()) {
E key = entry.getKey();
for(int index : entry.getValue()) {
keys[pos] = key;
for(int ooIndex = 0; ooIndex < numOtherArrays; ooIndex++) {
sortedOtherArrays[ooIndex][pos] = otherArrays[ooIndex][index];
}
pos++;
}
}
assert pos == numKeys : "Arrays should be full";
// Copy back to original arrays for in-place sort
for(int ooIndex = 0; ooIndex < numOtherArrays; ooIndex++) {
System.arraycopy(
sortedOtherArrays[ooIndex], 0,
otherArrays[ooIndex], 0,
numKeys);
}
}
これは、ほとんどのメモリ効率的な戦略ではありませんが、多くのコードではありません。
時間の複雑さはそれほど悪くありません。 O((M+1)*N*log(N))
のようになります。M
はotherArraysの数、N
は鍵の数です。最低でも狂った最悪の問題はありません。
おそらく ''データ構造が必要ですか? –
Thrasher
@Thrasherには同じ値がたくさんあるので、キーの値は上書きされます。私はあなたがHashMapを参照している場合は意味します。 – user3049183