Home > Enterprise >  Descending order of decimals
Descending order of decimals

Time:01-22

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.

  • Related