array input as [-100,50,0,56.6,90,0.12,.12,02.34,000.000]
Task: sort them in descending order
my output:[90,56.6,50,02.34,000.000,0.12,0,.12,-100]
Expected:[90,56.6,50,02.34,0.12,.12,0,000.000,-100]
import java.math.BigDecimal;
import java.util.*;
class Solution{
public static void main(String []args){
Scanner sc= new Scanner(System.in);
int n=sc.nextInt();
String []s=new String[n 2];
for(int i=0;i<n;i ){
s[i]=sc.next();
}
sc.close();
List<String> k = new ArrayList<>();
for(int i = 0;i<s.length-2;i ){
k.add(s[i]);
}
Collections.sort(k,Collections.reverseOrder());
k.toArray(s);
for(int i=0;i<n;i )
{
System.out.println(s[i]);
}
}
}
I tried converting array into list and sort it but it was able to sort positive and negative numbers but not decimal
CodePudding user response:
The problem is that the built-in sorting method for the List class, Collections.sort, uses the natural ordering of the elements which doesn't work well for decimal numbers. To fix this, you can use a custom Comparator class that compares the BigDecimal values of the elements in the list.
import java.math.BigDecimal;
import java.util.*;
class Solution {
public static void main(String []args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String []s = new String[n];
for(int i = 0; i < n; i ) {
s[i] = sc.next();
}
sc.close();
List<String> k = Arrays.asList(s);
Collections.sort(k, new Comparator<String>() {
public int compare(String s1, String s2) {
BigDecimal bd1 = new BigDecimal(s1);
BigDecimal bd2 = new BigDecimal(s2);
return bd2.compareTo(bd1);
}
});
for(String num : k) {
System.out.println(num);
}
}
}
This way the elements in the list are compared using the BigDecimal values and the list is sorted in descending order.
CodePudding user response:
The problem you are running into is the fact that you are not comparing doubles, you are comparing strings. Collections.sort() will call the String.compareTo() method which is leading to the behavior you are experiencing. The following code outputs the array you were expecting.
String[] yourArray = {"-100","50","0","56.6","90","0.12",".12","02.34","000.000"};
List<Double> k = new ArrayList<>();
for (int i = 0; i < yourArray.length; i ) {
k.add(Double.parseDouble(yourArray[i]));
}
Collections.sort(k, Collections.reverseOrder());
for (int i = 0; i < k.size(); i ) {
System.out.print(k.get(i) " ");
}
CodePudding user response:
Your code imports BigDecimal
, but doesn't use it. Try the following:
Change this:
String []s=new String[n 2];
for(int i=0;i<n;i ){
s[i]=sc.next();
}
To this:
BigDecimal [] s = new BigDecimal[n];
for(int i=0;i<n;i ){
s[i]=sc.nextBigDecimal();
}
And change
List<String> k = new ArrayList<>();
to
List<BigDecimal> k = new ArrayList<>();
Consider removing the intermediate array, and using your Scanner to put a new BigDecimal
into k
:
List<BigDecimal> k = new ArrayList<> ();
for (int i < 0; i < n; i ) {
k.add (sc.nextBigDecimal());
}
Note:
The sort
method of Collections
is stable. That means, it will not change the order of two objects that compare as equal.
BigDecimal.compareTo
regards 0.00
, 0.0000
, and 0
as equal to each other. 123
, 123.00
, 123.000
. So, in your example, if 0
precedes 000.000
before the sort, 0
will precede 000.00
after the sort. If 000.000
precedes 0
before the sort, 000.000
will precede 0
after the sort. If that is an issue for you, you will need a custom .compareTo
method or a custom Comparator
.