정렬 후 배열의 인덱스를 얻습니까?
사용자가 배열을 입력한다고 가정합니다. 예를 들면 다음과 같습니다.
Array = {France, Spain, France, France, Italy, Spain, Spain, Italy}
나는 그것의 길이를 알고 있었다
index
배열은 다음과 같습니다
index = {0, 1, 2, 3, 4, 5, 6, 7}
자, 정렬 후 Arrays.sort(Array);
newArray
같을 것이다:
newArray = {France, France, France, Italy, Italy, Spain, Spain, Spain}
그리고 newIndex
될 것 :
newIndex = {0, 2, 3, 4, 7, 1, 5, 6}
문제는 newIndex
입력 배열에서 어떻게 찾을 수 있습니까?
미리 감사드립니다
시작할 배열을 정렬하지 마십시오. 인덱스 배열을 정렬하고 값 을 인덱스로 사용하여 배열에 비교하는 비교기를 전달 합니다. 따라서 newIndex
정렬의 결과로 끝나고 실제 항목의 정렬 된 배열로 이동하는 것은 간단합니다.
이는 사용자 정의 방식으로 정수 배열을 정렬하는 것을 의미합니다. 즉 Integer[]
, 표준 Java 라이브러리 또는 sort(int[], IntComparator)
메소드 유형 과 함께 사용할 수있는 "IntComparator"인터페이스가있는 타사 라이브러리를 사용하는 것을 의미 합니다.
편집 : 좋아, 여기 비교기의 예가 있습니다. 단순성을 위해 "원래"문자열 배열 만 정렬한다고 가정하겠습니다. 그리고 nullity 테스트는 신경 쓰지 않습니다.
public class ArrayIndexComparator implements Comparator<Integer>
{
private final String[] array;
public ArrayIndexComparator(String[] array)
{
this.array = array;
}
public Integer[] createIndexArray()
{
Integer[] indexes = new Integer[array.length];
for (int i = 0; i < array.length; i++)
{
indexes[i] = i; // Autoboxing
}
return indexes;
}
@Override
public int compare(Integer index1, Integer index2)
{
// Autounbox from Integer to int to use as array indexes
return array[index1].compareTo(array[index2]);
}
}
다음과 같이 사용합니다.
String[] countries = { "France", "Spain", ... };
ArrayIndexComparator comparator = new ArrayIndexComparator(countries);
Integer[] indexes = comparator.createIndexArray();
Arrays.sort(indexes, comparator);
// Now the indexes are in appropriate order.
Java 8 Stream API로이를 달성하는 간결한 방법,
final String[] strArr = {"France", "Spain", "France"};
int[] sortedIndices = IntStream.range(0, strArr.length)
.boxed().sorted((i, j) -> strArr[i].compareTo(strArr[j]) )
.mapToInt(ele -> ele).toArray();
TreeMap<String,Int> map = new TreeMap<String,Int>();
for( int i : indexes ) {
map.put( stringarray[i], i );
}
이제 정렬 순서로 인덱스를 검색하려면 map.values ()를 반복하고 문자열을 가져 오려면 map.keySet ()를, String-index-Pairs를 얻으려면 map.entrySet ()을 반복합니다.
@Skeet의 코드를 기반으로 다음을 만들었습니다. 좀 더 OOPie라고 생각합니다. 몰라요.
public static <T extends Comparable<T>> List<Integer> sortIndex(List<T> in) {
ArrayList<Integer> index = new ArrayList<>();
for (int i = 0; i < in.size(); i++) {
index.add(i);
}
Collections.sort(index, new Comparator<Integer>() {
@Override
public int compare(Integer idx1, Integer idx2) {
return in.get(idx1).compareTo(in.get(idx2));
}
});
return index;
}
들어오는 다른 개체에 대한 비교기 코드가있는 정렬 및 인덱싱을 구현하는 클래스 대신 원래 배열의 개체가 Comparable 인터페이스를 구현해야합니다. 많은 관심 객체가 자연스러운 순서를 가지고 있으며 Comparable 인터페이스가 이미 구현되어있는 것 같습니다.
public static void main(String[] args) {
List<Integer> a1 = new ArrayList<>(Arrays.asList(2, 3, 9, 4, 1));
// Just pass in the list to have its indexes sorted by the natural ordering
List<Integer> idx = sortIndex(a1);
List<Double> a2 = new ArrayList<>(Arrays.asList(1.0, 5.3, 5.2, -3.1, 0.3));
idx = sortIndex(a2);
List<numBits> a3 = new ArrayList<>();
for (int i = 0; i < 10; i++) {
a3.add(new numBits(i));
}
// If you need to sort the indexes of your own object, you must implement
// the Comparable Interface.
idx = sortIndex(a3);
}
static class numBits implements Comparable<numBits> {
private int a;
public numBits(int i) {
a = i;
}
public String toString() {
return Integer.toString(a);
}
// Sort by the total number of bits in the number.
@Override
public int compareTo(numBits that) {
if (Integer.bitCount(this.a) < Integer.bitCount(that.a))
return -1;
if (Integer.bitCount(this.a) > Integer.bitCount(that.a))
return 1;
return 0;
}
}
양수 값으로 기본 float 또는 int 배열을 반복적으로 정렬하는 시나리오가있는 경우 아래와 같은 방법이 비교기를 사용하는 것보다 훨씬 더 나은 (x3 ~ x4) 속도를 제공합니다.
long time = System.currentTimeMillis();
for (int i = 0; i < iters; i++) {
float[] array = RandomUtils.randomFloatArray(-1, 1, 3000);
long[] valueKeyPairs = new long[array.length];
for (int j = 0; j < array.length; ++j) {
valueKeyPairs[j] = (((long) Float.floatToIntBits(array[j])) << 32) | (j & 0xffffffffL);
}
Arrays.sort(valueKeyPairs);
/**Then use this to retrieve the original value and index*/
//long l = valueKeyPairs[j];
//float value = Float.intBitsToFloat((int) (l >> 32));
//int index = (int) (l);
}
long millis = System.currentTimeMillis() - time;
이를 수행 할 수있는 한 가지 방법은 원래 색인과 국가 이름을 별도의 클래스로 래핑하는 것입니다. 그런 다음 이름을 기준으로 배열을 정렬합니다. 이렇게하면 원래 색인이 보존됩니다.
언뜻 보면 그런 식으로 매핑하는 것입니다.
Map <Integer, String> map = new HashMap<Integer, String>();
map.put(0, "France");
map.put(1, "Spain");
map.put(2, "France");
and then sort them by value like that and then you can know their indexes and values (key, values) just print the map
Iterator mapIterator = map.keySet().iterator();
while (mapIterator .hasNext()) {
String key = mapIterator.next().toString();
String value = map.get(key).toString();
System.out.println(key + " " + value);
}
참고URL : https://stackoverflow.com/questions/4859261/get-the-indices-of-an-array-after-sorting
'development' 카테고리의 다른 글
개체 컬렉션 정렬 (0) | 2020.12.11 |
---|---|
내 앱에서 직접 "iTunes에서 평가"링크를 사용합니까? (0) | 2020.12.11 |
java.lang.NoClassDefFoundError : org / apache / commons / fileupload / FileItemFactory (0) | 2020.12.11 |
테이블의 일부에 mysqldump를 사용하는 방법은 무엇입니까? (0) | 2020.12.11 |
Scala에서“view”는 무엇을합니까? (0) | 2020.12.11 |