Reputation: 1034
The question is to sort an array of Strings, based on the length of the strings.
For example
input = {"cat", "star", "act", "gid", "arts", "dog", "rats"}
output = {"cat", "act", "gid", "dog", "star", "arts", "rats"}
I did it using Insertion sort(using the length of the strings instead of the strings themselves). My question:is there a better way to do it?
An alternative I thought of is - use a TreeMap
to store each string and its length as value (assume the strings are unique in the given array). Then sort it based on its values. The running time would be O(nlogn)
and space complexity would be O(n)
. Do you think this is a better approach?
EDIT: Sorry for not mentioning this earlier - I want to do this without using Arrays.sort()
or a custom comparator.
Code sample for insertion sort:
public static String[] insertionSort(String[] arr) {
for(int i=1;i<arr.length;i++) {
int j = 0;
for(;j<i;j++) {
if(arr[j].length() > arr[j+1].length()) {
String temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
return arr;
}
Upvotes: 4
Views: 16125
Reputation: 2122
Question: Sort an array of strings according to string lengths. We can do it Using Streams in Java 8
public class SortStringsAccordingToLength {
public static void main(String[] args) {
List<String> sampleStrings = Arrays.asList("Protijayi", "Gina", "Gini", "Soudipta");
System.out.println(lengthSortUsingSorted1(sampleStrings));
System.out.println(lengthSortUsingSorted2(sampleStrings));
System.out.println(lengthSortUsingSorted3(sampleStrings));
System.out.println(lengthSortUsingSorted4(sampleStrings));
}
private static List<String> lengthSortUsingSorted4(List<String> list) {
list.sort((a, b) -> Long.compare(a.length(), b.length()));
System.out.println(list);
return list;
}
private static List<String> lengthSortUsingSorted3(List<String> sampleStrings) {
List<String> list1 = sampleStrings.stream()
.sorted(Comparator.comparingLong(String::length).thenComparing(Comparator.naturalOrder()))
.collect(Collectors.toList());
return list1;
}
private static List<String> lengthSortUsingSorted2(List<String> sampleStrings) {
List<String> list1 = sampleStrings.stream().sorted(Comparator.comparingInt(String::length))
.collect(Collectors.toList());
return list1;
}
public static List<String> lengthSortUsingSorted1(List<String> sampleStrings) {
List<String> list1 = sampleStrings.stream().sorted((s1, s2) -> s1.length() - s2.length())
.collect(Collectors.toList());
return list1;
}
}
Upvotes: 0
Reputation: 129
String[] strArray = new String[] { "cat", "star", "act", "gid", "arts",
"dog", "rats" };
List<String> strings = Arrays.asList(strArray);
strings.sort((s1, s2) -> Math.abs(s1.length()) - Math.abs(s2.length()));
System.out.println(strings);
Upvotes: 0
Reputation: 129
public class SortArrayOfStringOnLength {
public static void main(String[] args) {
String[] strArray = new String[] { "cat", "star", "act", "gid", "arts",
"dog", "rats" };
printArray(strArray);
String[] outputArray = getSortedArray(strArray);
printArray(outputArray);
}
private static String[] getSortedArray(String[] strArray) {
Map map = new TreeMap();
for (int i = 0; i < strArray.length; i++) {
String str = strArray[i];
if (map.containsKey(str.length())) {
List list = (List) map.get(str.length());
list.add(str);
map.put(str.length(), list);
} else {
List list = new ArrayList();
list.add(str);
map.put(str.length(), list);
}
}
Set set = map.keySet();
Iterator itr = set.iterator();
int outArrayIndex = 0;
String[] outputArray = new String[strArray.length];
while (itr.hasNext()) {
Integer intValue = (Integer) itr.next();
List list = (List) map.get(intValue);
for (int i = 0; i < list.size(); i++) {
outputArray[outArrayIndex] = (String) list.get(i);
outArrayIndex++;
}
}
return outputArray;
}
private static void printArray(String[] strArray) {
System.out.println("*****************");
for (int i = 0; i < strArray.length; i++) {
System.out.println(strArray[i]);
}
}
}
Upvotes: 0
Reputation: 14278
String[] str={"umbrella","apple", "baby", "cat","rat","obnoxious"};
Arrays.sort(str, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.length()-o2.length();
}
});
Upvotes: 3
Reputation: 6374
You can use a Comparator as following:
public static class OrderStringByLength implements Comparator<String> {
@Override
public int compare(String s1, String s2) {
int c = s1.length() - s2.length();
return (c != 0) ? c : s1.compareTo(s2);
}
}
Then you can sort the array as follows:
Arrays.sort(input, new OrderStringByLength());
Upvotes: 0
Reputation: 3579
If you can use a Collection instead (e.g an ArrayList will be great in your case), you can use Collections.sort to do the work for you. It's fast and clean. See: java.util.List
You will need a custom comparator.
public class StringComparator implements Comparator<String>
{
@Override
public int compare(String s1, String s2)
{
return s1.length()-s2.length();
}
}
Upvotes: 0
Reputation: 26094
Try this one.
Your input
String[] input = {"cat", "star", "act", "gid", "arts", "dog", "rats"};
Your Comparator
class SampleComparator implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
return new Integer(o1.length()).compareTo(o2.length());
}
}
Your Sorting
Collections.sort(in, new SampleComparator());
Your output
output = {"cat", "act", "gid", "dog", "star", "arts", "rats"}
Upvotes: 5
Reputation: 87
There are a number of better ways to do it. For insertion sort, we're talking O (n^2). A much better sorting algorithm would be something like mergesort (better worst-case) or quicksort (better on average). Since this is a length-based sort, there are a number of approaches that can be taken. You are going to have to calculate the length of each string at some point. What you could do is create an array of ints that correspond to the lengths of the words at the same respective index. Then you can run mergesort or quicksort on the ints and be sure to flip the strings around at the same time. The end result would be a non-decreasing array of ints and a non-decreasing array of strings.
Upvotes: 2