Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
443 views
in Technique[技术] by (71.8m points)

java - Sort ArrayList but keep order of the original indexes

There are two int arrays and an array list called costs and shipping. I want an ArrayList that has the smallest to the largest total price (for example costs[0] + shipping[0]) but reorder the two int arrays to match the ArrayList:

Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int[] costs = new int[n];
int[] shipping = new int[n];
ArrayList<Integer> totalCosts = new ArrayList<>();

For example, say that costs is [1, 5, 2, 3] and shipping is [2, 3, 2, 4], so totalCosts would be {3, 8, 4, 7} and would be sorted to {3, 4, 7, 8}. I want costs and shipping to be reordered so they correspond to the totals, so costs would be [1, 2, 3, 5] and shipping would be [2, 2, 4, 3].


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is a solution that does not use a map. Instead we have a custom Comparator that uses the sum of costs and shipping to sort the array positions. Then we create new arrays and pick the values from the sorted positions in the old arrays.

public static void main(String[] args) {
    int n = 4;
    int[] costs = {1, 5, 2, 3};
    int[] shipping = {2, 3, 2, 4};
    Integer[] totals = new Integer[n];
    for(int i = 0; i < n; ++i) {
        totals[i] = i;
    }

    Arrays.sort(totals, Comparator.comparingInt(k -> (costs[k] + shipping[k])));

    int[] newCosts = new int[n];
    int[] newShipping = new int[n];
    for(int i = 0; i < n; ++i) {
        newCosts[i] = costs[totals[i]];
        newShipping[i] = shipping[totals[i]];
    }

    for(int i = 0; i < n; ++i){
        System.out.println((i + 1) + ": Cost=" + newCosts[i] + ", Shipping=" + newShipping[i] + ", Total=" + (newCosts[i] + newShipping[i]));
    }
}

Explanation

The totals array contains the list of index from 0 to n (4 in the sample). Arrays.sort() sorts the index using the Comparator which, given an index, extracts the totals for that position. The totals array will, after sorting, list index of the sums of cost and shipping in order.

After that we can create new cost and shipping arrays using the sorted indexes.

Edit

Taking ttzn's advice from the comments, you can compress the code to this:

public static void main(String[] args) {
    int n = 4;
    int[] costs = {1, 5, 2, 3};
    int[] shipping = {2, 3, 2, 4};

    int[] totals = IntStream.range(0, n).boxed().sorted(Comparator.comparingInt(k -> (costs[(int)k] + shipping[(int)k]))).mapToInt(Integer::intValue).toArray();

    int[] newCosts = IntStream.of(totals).map(i -> costs[i]).toArray();
    int[] newShipping = IntStream.of(totals).map(i -> shipping[i]).toArray();

    for (int i = 0; i < n; ++i) {
        System.out.println((i + 1) + ": Cost=" + newCosts[i] + ", Shipping=" + newShipping[i] + ", Total=" + (newCosts[i] + newShipping[i]));
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...