有两个 int 数组和一个名为 cost 和 shipping 的数组列表。我想要一个总价从最小到最大的 ArrayList(例如成本 [0] + 运输 [0]),但重新排序两个 int 数组以匹配 ArrayList:
find "A notional thesis title" in field "Title"
例如,假设成本是 [1, 5, 2, 3] 并且运费是 [2, 3, 2, 4],所以总成本将为 {3, 8, 4, 7} 并且将被排序为{3, 4, 7, 8}。我希望对成本和运费进行重新排序,使它们与总数相对应,因此成本为 [1, 2, 3, 5],运费为 [2, 2, 4, 3]。
答案 0 :(得分:1)
这是一个不使用地图的解决方案。相反,我们有一个自定义的 Comparator,它使用成本和运费的总和来对数组位置进行排序。然后我们创建新数组并从旧数组的排序位置中选取值。
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]));
}
}
说明
totals 数组包含从 0 到 n 的索引列表(示例中为 4)。 Arrays.sort()
使用 Comparator 对索引进行排序,在给定索引的情况下,它会提取该位置的总数。 totals 数组排序后,将按顺序列出成本和运费总和的索引。
之后,我们可以使用排序索引创建新的成本和运输数组。
编辑
根据评论中的 ttzn 建议,您可以将代码压缩为:
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]));
}
}
答案 1 :(得分:1)
这是一个无需构建地图的基于流的解决方案。
构建了一个 Stream<int[]>
,在 int[]
数组中存储总数和索引,
使用自定义比较器对这些数组进行排序(首先按总数,然后按索引)
有意使用 peek
和 AtomicInteger
重新排序输入 costs
和 ships
数组
注意:然而,这可能被认为是“滥用”,因为数据流外的副作用更新
构建并返回总数数组。
public static int[] getTotals(int[] costs, int[] ships) {
assert costs.length == ships.length;
int[] copyCosts = Arrays.copyOf(costs, costs.length);
int[] copyShips = Arrays.copyOf(ships, ships.length);
AtomicInteger ix = new AtomicInteger(0);
return IntStream.range(0, costs.length)
.mapToObj(i -> new int[]{ costs[i] + ships[i], i })
.sorted(Comparator.<int[]>
comparingInt(p -> p[0])
.thenComparingInt(p -> p[1])
) // get sorted Stream<int[]>
.peek(p -> {
costs[ix.get()] = copyCosts[p[1]];
ships[ix.getAndIncrement()] = copyShips[p[1]];
})
.mapToInt(p -> p[0])
.toArray();
}
答案 2 :(得分:0)
public List<Integer> sortPrices(int[] cost, int[] shipping) {
List<Integer> result = new ArrayList<>();
TreeMap<Integer, List<int[]>> map = new TreeMap<>();
int length = cost.length;
int[] origCost = new int[length];
int[] origShipping = new int[length];
for (int i = 0; i < length; i++) {
int price = cost[i] + shipping[i];
int[] arr = {i, i};
map.putIfAbsent(price, new ArrayList<>());
map.get(price).add(arr);
origCost[i] = cost[i];
origShipping[i] = shipping[i];
}
int j = 0;
for (int price : map.keySet()) {
for (int[] arr : map.get(price)) {
int ci = arr[0];
int si = arr[1];
cost[j] = origCost[ci];
shipping[j] = origShipping[si];
j++;
result.add(price);
}
}
return result;
}
答案 3 :(得分:0)
我是用python解决的
只要了解循环逻辑,你就可以做到。
for i in range(len(total)):
for j in range(len(total)):
if sorted_total[i]==total[j]:
new_costs[i]=costs[j]
new_shipping[i]=shipping[j]
print("i ",i)
print("j ",j)
break