0

I need to sort strings containing numbers

Eg :

 input : {"1","12","12","2","ABC","a"}

 Expected output: 1 2 12 a ABC

 My output  :1 2 12 12 a ABC 

I am not able to remove duplicate. can anyone help me with this ?

Below is the code I used for sorting

public static String[] Sort(String[] list) {
    Comparator<String> comp = new Comparator<String>() {
        public int compare(String str1, String str2) {
            try {
                int num1 = Integer.parseInt(str1);
                int num2 = Integer.parseInt(str2);
                return Integer.compare(num1, num2);
            }
            catch (NumberFormatException e) {
                return str1.compareTo(str2);
            }
        }
    };
    Arrays.sort(list, comp);
    return list;
}

Thanks in Advance

5 Answers5

1

The easiest way of approaching this problem is using Streams. This would let us tackle this problem using a single line of code.

String[] sorted = Arrays.stream(list).distinct().sorted((s1,s2)->compare(s1,s2)).toArray(String[]::new);

edit: added use of the given comparator for full support of both number strings and other strings.

Also, the comparator should compare the strings after toLowerCase() have been applied. Resulting in

catch (NumberFormatException e) {
            return str1.toLowerCase().compareTo(str2.toLowerCase());
}
Irad Ohayon
  • 174
  • 6
  • I think this is right, but it doesn't give the desired output, which may be unacheavable be built-in functions... – deHaar Aug 24 '20 at 14:30
  • 1
    With the addition of `toLowerCase()` in the comparator, this works and is therefore the most correct answer. I was about to edit mine as I got it working by splitting number strings and letter strings and treating them separately, but that's much more convoluted than this far more elegant approach. I'll delete it instead to avoid misleading people that might check this question in the future. – JustAnotherDeveloper Aug 24 '20 at 14:45
  • The above doesn't compile. – WJS Aug 24 '20 at 15:51
  • @WJS Thanks, I fixed the syntax error in the code. Make sure you import the required libraries when working with streams (all under java.util.*) – Irad Ohayon Aug 24 '20 at 16:18
  • You're welcome. But I was primarily referring to the `Comparator` in the `sorted` method. `compare` needs to be qualified. – WJS Aug 24 '20 at 16:36
0

Set can be used to remove dublicates

public static Set<String> sort(String[] list) {
    Comparator<String> comp = new Comparator<String>() {
        public int compare(String str1, String str2) {
            try {
                int num1 = Integer.parseInt(str1);
                int num2 = Integer.parseInt(str2);
                return Integer.compare(num1, num2);
            }
            catch (NumberFormatException e) {
                return str1.compareTo(str2);
            }
        }
    };
    Set<String> set = new TreeSet<String>(comp);
    set.addAll(Arrays.asList(list));
    System.out.println(set);
    return set;
}
Ganesh
  • 54
  • 3
0

You want to sort as well remove duplicate. it means its two process that is difficult for comparator to do both, you need to get distinct string in array, so sort and then get only distinct, there are lot of ways, but i did which is easy to understand:

public static String[] Sort(String[] list) {
        Comparator<String> comp = new Comparator<String>() {
            public int compare(String str1, String str2) {
                try {
                    int num1 = Integer.parseInt(str1);
                    int num2 = Integer.parseInt(str2);
                    return Integer.compare(num1, num2);
                }
                catch (NumberFormatException e) {
                    return str1.compareTo(str2);
                }
            }
        };
        Arrays.sort(list, comp);
        ArrayList<String> new_list = new ArrayList<String>;
        if(list.length()>0){ 
          new_list.add(list[0]);
        }
        for(String s : list){
         //comparing with the last added string in list, if not same then add
          if(!new_list.get(new_list.size()-1).equals(s)){
             new_list.add(s);
           }
        }
        return new_list.toArray(new String[new_list.size()]);
    }
Rohit Maurya
  • 154
  • 1
  • 1
  • 10
0

Try this. I included a more complicated array of the same elements to verify.

String[] vals = {"1","ABC","12","a", "1", "2", "12","2","ABC", "a", "ABC","a"};


Comparator<String> comp = ((a,b)-> {
   if (a.matches("\\d+") && b.matches("\\d+")) {
       return Integer.compare(Integer.valueOf(a), Integer.valueOf(b));
   } else {
            return a.toLowerCase().compareTo(b.toLowerCase());
   }
});

String[] result = Arrays.stream(vals).distinct().sorted(comp).toArray(String[]::new);
            
System.out.println(Arrays.toString(result));

Prints

[1, 2, 12, a, ABC]
WJS
  • 36,363
  • 4
  • 24
  • 39
0

You've asked 2 differents question ! To answear to the first:

Comparator<String> comparator = new Comparator<String>() {
        
        public int compare(String str1, String str2) {
            return isInteger(str1) && isInteger(str2)
                   ? Integer.compare(num1, num2)
                   : isInteger(str1) 
                   ? -1
                   : isInteger(str2)
                   ? 1
                   : str1.compareTo(str2);
        }
    };

private boolean isInteger(String value) {
    try {
        Integer.parseInt(value);
        return true;
    }
    catch (NumberFormatException e) {
        return false;
    }
Halayem Anis
  • 7,654
  • 2
  • 25
  • 45