It is requested to sort the list below from smallest to largest.
Array input: [-100, 50, 0, 56.6, 90, 0.12, .12, 02.34, 000.000]
My Code:
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 wrote the above code but I am getting this result.
My Output: [90, 56.6, 50, 02.34, 000.000, 0.12, 0, .12, -100]
The expected result is like this.
Expected: [90, 56.6, 50, 02.34, 0.12, .12, 0, 000.000, -100]
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 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:
The problem is that you are just sorting the value as strings. What you want to do is sort them as if they are doubles. You need to provide a comparator that compare the double values instead of string.
import java.util.*;
public class Main{
public static void main(String[] args) {
String []s = {"-100","50","0","56.6","90","0.12",".12","02.34","000.000"};
System.out.println("Before : " Arrays.toString(s));
Arrays.sort(s, (x,y)->Double.valueOf(y).compareTo(Double.valueOf(x)));
System.out.println("Actual : " Arrays.toString(s));
System.out.println("Expected: [90, 56.6, 50, 02.34, 0.12, .12, 0, 000.000, -100]");
}
}
output
Before : [-100, 50, 0, 56.6, 90, 0.12, .12, 02.34, 000.000]
Actual : [90, 56.6, 50, 02.34, 0.12, .12, 0, 000.000, -100]
Expected: [90, 56.6, 50, 02.34, 0.12, .12, 0, 000.000, -100]
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. The values 123
, 123.00
, 123.000
are another example. So, in your example, if 0
precedes 000.000
before the sort, 0
will precede 000.000
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 can create a custom Comparator
, which might use the scale
method of BigDecimal. Another option is to create a custom class, which implements Comparable
.