[英]Sort all even numbers in ascending order and then sort all odd numbers in descending order in a collection
This is an interview question. 这是一个面试问题。
There are some random numbers given (let's say in an integer array). 给出了一些随机数(假设在整数数组中)。
12 67 1 34 9 78 6 31
6 12 34 78 67 31 9 1
Any collection that supports sorting with a custom comparer will do - even an array. 任何支持使用自定义比较器进行排序的集合都可以 - 甚至是数组。 Implement your custom comparator as follows:
按如下方式实现自定义比较器:
public int compare(int x, int y) {
if (x&1 == y&1) {
// Both numbers are odd or both numbers are even
if (x&1 == 0) {
// Both numbers are even: compare as usual
return Integer.compare(x, y);
} else {
// Both numbers are odd: compare in reverse
return Integer.compare(y, x);
}
}
// One is odd, the other one is even
if (x&1 == 0) {
return -1;
}
return 1;
}
You could do as follows 你可以这样做
public ArrayList<Integer> sort(Integer[] input) {
int length = input.length;
ArrayList<Integer> oddNumber = new ArrayList<Integer>(0);
ArrayList<Integer> evenNumber = new ArrayList<Integer>(0);
for (int i = 0; i < length; i++) {
Integer val = input[i];
if(isEven(val)){
evenNumber.add(val);
} else {
oddNumber.add(val);
}
}
Collections.sort(evenNumber);
Collections.sort(oddNumber, Collections.reverseOrder());
evenNumber.addAll(oddNumber);
return evenNumber;
}
public boolean isEven(Integer x) {
return x % 2 == 0;
}
EDIT 编辑
I implemented a comparator based on Jesper algorithm. 我实现了一个基于Jesper算法的比较器。
public ArrayList<Integer> sort(Integer[] input) {
ArrayList<Integer> output = new ArrayList<Integer>(0);
output.addAll(Arrays.asList(input));
Collections.sort(output, new EvenOddComparator());
return output;
}
public class EvenOddComparator implements Comparator<Integer>
{
final int BEFORE = -1;
final int EQUAL = 0;
final int AFTER = 1;
@Override
public int compare(Integer o1, Integer o2) {
if (o1 % 2 == 0 && o2 % 2 != 0) {
return BEFORE;
} else if (o1 % 2 != 0 && o2 % 2 == 0) {
return AFTER;
} else if (o1 % 2 == 0 && o2 % 2 == 0) {
return o1.compareTo(o2);
} else if (o1 % 2 != 0 && o2 % 2 != 0) {
return o2.compareTo(o1);
}
return EQUAL;
}
}
Cheers. 干杯。
Here's the code : 这是代码:
@Override
public int compare(Integer o1, Integer o2) {
if (o1 % 2 ==0)
{
if (o2 % 2 == 0)
{
if (o1 < o2)
return -1;
else
return 1;
}
//if (o2 % 2 != 0)
else
{
return -1;
}
}
else
{
if (o2 % 2 != 0)
{
if (o1 < o2)
return 1;
else
return -1;
}
//if (o2 % 2 == 0)
else
{
return 1;
}
}
}
package com.java.util.collection;
import java.util.Arrays;
import java.util.Collections;
public class EvenOddSorting {
public static void eventOddSort(int[] arr) {
int i =0;
int j =arr.length-1;
while(i<j) {
if(isEven(arr[i]) && isOdd(arr[j])) {
i++;
j--;
} else if(!isEven(arr[i]) && !isOdd(arr[j])) {
swap(i,j,arr);
} else if(isEven(arr[i])){
i++;
} else{
j--;
}
}
display(arr);
// even number sorting
Arrays.sort(arr,0,i);
insertionSort(arr,i,arr.length);
// odd number sorting
display(arr);
}
/**
* Instead of insertion sort, you can use merge or quick sort.
* @param arr
* @param firstIndex
* @param lastIndex
*/
public static void insertionSort(int[] arr, int firstIndex, int lastIndex){
for(int i=firstIndex+1;i<lastIndex;i++){
int key =arr[i];
int j=i-1;
while(j>=firstIndex && key > arr[j]) {
arr[j+1] = arr[j];
arr[j] =key;
j=j-1;
}
System.out.println("\nAfter "+(i+1) +" Iteration : ");
display(arr);
}
}
public static void display(int[] arr) {
System.out.println("\n");
for(int val:arr){
System.out.print(val +" ");
}
}
private static void swap(int pos1, int pos2, int[] arr) {
int temp = arr[pos1];
arr[pos1]= arr[pos2];
arr[pos2]= temp;
}
public static boolean isOdd(int i) {
return (i & 1) != 0;
}
public static boolean isEven(int i) {
return (i & 1) == 0;
}
public static void main(String[] args) {
int arr[]={12, 67, 1, 34, 9, 78, 6, 31};
eventOddSort(arr);
}
}
If it is not required that you implement the whole sorting algorithm yourself, you could just use Collections.sort(list, comparator)
, and you'll need to supply your own Comparator<Integer>
implementation that compares the numbers and returns a result so that the numbers are sorted in the order that is defined by the rules. 如果您不需要自己实现整个排序算法,您可以使用
Collections.sort(list, comparator)
,并且您需要提供自己的Comparator<Integer>
实现,该实现比较数字并返回结果,数字按规则定义的顺序排序。
The comparator would have to implement these rules: 比较国必须实施这些规则:
If you have the numbers in an array instead of a List
, then use Arrays.sort(array, comparator)
. 如果您有数组而不是
List
,那么使用Arrays.sort(array, comparator)
。
I dont think any one Collection is necessarily better than the other, I would use something that extends a list rather than a set though and definitely not a map. 我不认为任何一个集合必然比另一个更好,我会使用扩展列表而不是集合的东西,但绝对不是地图。
What I would do is that in my Collection.sort
call, I would check if the number mod 2 ( number%2
) is zero then I would would do a simple compareTo
otherwise I would do an Integer.MAX_INT - oddNumber
and then do a compareTo. 我要做的是在我的
Collection.sort
调用中,我会检查数字mod 2( number%2
)是否为零然后我会做一个简单的compareTo
否则我会做一个Integer.MAX_INT - oddNumber
然后做一个相比于。 That way the larger the odd number the smaller the generated number and it will be sorted to the end of the list in a descending order. 这样,奇数越大,生成的数字越小,它将按降序排序到列表的末尾。
Integer num1 = (o1%2 == 0)? new Integer(o1) : new Integer(Integer.MAX_INT - o1);
Integer num2 = (o2%2 == 0)? new Integer(o2) : new Integer(Integer.MAX_INT - o2);
return num1.compareTo(num2);
Above is just sudo code, don't take it too literally, its just to give you an idea. 以上只是sudo代码,不要过于字面意思,只是为了给你一个想法。
If all numbers are positive, you can multiply your odd numbers by "-1", do a standard sort, then again multiply all odd numbers by "-1". 如果所有数字都是正数,则可以将奇数乘以“-1”,进行标准排序,然后再将所有奇数乘以“-1”。
If you want the order as in a question, you'll also have to swap "negative" and "positive" array parts before the 2nd multiplication. 如果您希望订单在问题中,您还必须在第二次乘法之前交换“负”和“正”数组部分。
Total overhead: 3 more loops in addition to a chosen sort algorithm. 总开销:除了选择的排序算法之外还有3个循环。
List<Integer> numbers = new ArrayList<Integer>();
//add some numbers here
//12 67 1 34 9 78 6 31 <-- in the list
for (int i = 0; i < numbers.size(); i++) {
if (numbers.get(i) % 2 == 1) {
numbers.set(i, numbers.get(i) * (-1));
}
}
//12 -67 -1 34 -9 78 6 -31 <-- before sort
sort(numbers);
//-67 -31 -9 -1 6 12 34 78 <-- after sort
swapNegativeAndPositiveParts(numbers);
//6 12 34 78 -67 -31 -9 -1 <-- after swap
for (int i = 0; i < numbers.size(); i++) {
if (numbers.get(i) % 2 == 1) {
numbers.set(i, numbers.get(i) * (-1));
}
}
//6 12 34 78 67 31 9 1 <-- after second multiplication
You can use one data structure which holds all the numbers and then, create two SortedSet s, one for odd and one for even. 您可以使用一个包含所有数字的数据结构,然后创建两个SortedSet ,一个用于奇数,一个用于偶数。 The sorted set can take a
Comparator
as a parameter which allows you to sort elements while you enter data. 排序集可以将
Comparator
作为参数,允许您在输入数据时对元素进行排序。
Once that you will have gone through all the numbers, create a new collection which merges the two sorted sets. 一旦你完成所有数字,就创建一个新的集合,合并两个有序的集合。
You can also replace the sorted sets by using two Lists
. 您还可以使用两个
Lists
替换已排序的集。 Once that you have added all the numbers, call Collections.sort()
on the lists and then merge as before. 一旦你添加了所有数字,在列表上调用
Collections.sort()
然后像以前一样合并。
Ad1. AD1。 We need to create a
Comparator<Tnteger>
that works with this rules. 我们需要创建一个符合此规则的
Comparator<Tnteger>
。
Ad2. AD2。 I do not understand.
我不明白。
Like this: 像这样:
var list = new List<int>{1,5,2,6,3,9,10,11,12};
var sorted = list.Where (l => l%2 ==0).OrderBy (l=>l).Union(list.Where (l => l%2 != 0).OrderByDescending (l=>l));
I would normalise all the numbers and then sort them. 我会将所有数字标准化然后对它们进行排序。
public static void main(String[] args) {
int[] values = {Integer.MIN_VALUE, 0, Integer.MAX_VALUE - 1, Integer.MIN_VALUE + 1, -1, 1, Integer.MAX_VALUE};
for (int i = 0; i < values.length; i++) {
int value = encode(values[i]);
assert decode(value) == values[i];
values[i] = value;
}
Arrays.sort(values);
for (int i = 0; i < values.length; i++)
// give back the original value.
values[i] = decode(values[i]);
System.out.println(Arrays.toString(values));
}
private static int decode(int value) {
return value >= 0
? Integer.MAX_VALUE - (value << 1)
: Integer.MIN_VALUE + (value << 1);
}
private static int encode(int value) {
return (value & 1) == 0
? (value >> 1) + Integer.MIN_VALUE / 2
: Integer.MAX_VALUE / 2 - (value >> 1);
}
prints 版画
[-2147483648, 0, 2147483646, 2147483647, 1, -1, -2147483647]
There is extra shifting here so very large numbers are not mangled. 这里有额外的转移,所以非常大的数字不会被破坏。 (which is why the number is divided by two)
(这就是数字除以2的原因)
I just coded a fast example, as below: 我刚刚编写了一个快速示例,如下所示:
public class CustomSorting {
public static void main(String[] args) {
Integer[] intArray = new Integer[] {12, 67, 1, 34, 9, 78, 6, 31};
Arrays.sort(intArray, new Comparator() {
@Override
public int compare(Object obj1, Object obj2) {
Integer int1 = (Integer) obj1;
Integer int2 = (Integer) obj2;
int mod1 = Math.abs(int1%2);
int mod2 = Math.abs(int2%2);
return ((mod1 == mod2) ? ((mod1 == 0) ? int1.compareTo(int2) : int2.compareTo(int1)) : ((mod1 < mod2) ? -1 : 1));
}
});
}
}
Output : 输出 :
[6, 12, 34, 78, 67, 31, 9, 1]
[6,12,34,78,67,31,9,1]
in Java :- Best Approach, Minimum Complexity 在Java中: - 最佳方法,最低复杂性
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;
public class EvenOddSorting {
public static void main(String[] args) {
// TODO Auto-generated method stub
int i, size;
ArrayList<Integer> listEven = new ArrayList<Integer>();
ArrayList<Integer> listOdd = new ArrayList<Integer>();
ArrayList<Integer> finalList = new ArrayList<Integer>();
Scanner sc = new Scanner(System.in);
System.out.println("Enter Array Size : ");
size = sc.nextInt();
int A[] = new int[size];
for (i = 0; i < size; i++) {
A[i] = sc.nextInt();
}
for (i = 0; i < size; i++){
if (A[i] % 2 == 0){
listEven.add(A[i]);
}
else if (A[i] % 2 != 0) {
listOdd.add(A[i]);
}
}
Collections.sort(listEven);
Collections.sort(listOdd);
Collections.reverse(listOdd);
finalList.addAll(listOdd);
finalList.addAll(listEven);
System.out.println("Result is : "+finalList);
}
}
Output :- 输出: -
Enter Array Size : 10 输入数组大小:10
1 2 3 4 5 6 7 8 9 10 Result is : [9, 7, 5, 3, 1, 2, 4, 6, 8, 10] 1 2 3 4 5 6 7 8 9 10结果是:[9,7,5,3,1,2,4,6,8,10]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.