So I know how to sort a Java array of ints or floats (or other data types). But what if it was a string array String[] arr = {} where the array contained elements like 2x^2, 4x^4. As you can see, there are several indices that have integers, which could be sorted.
The way I would think to sort this is to splice out the number at an index. Sort those numbers, then map each old index to the new index.
I feel like there is a better way.
The essential question: Does a sorting method exist that can sort a string array based on an integer at a certain index of each index?
If you are wondering, here would be some sample inputs and outputs of an algorithm as such.
Array: {"2x^3","2x^0","1x^1"}
Output:{"2x^3","1x^1","2x^0"} // Sorted based on last index
static final Comparator<String> myComparator =
new Comparator<String>() {
public int compare(String s1, String s2)
{
// split s1 and s2, compare what you need
// and return the result.
// e.g.
// char digit1 = s1[s1.length() - 1];
// char digit2 = s2[s2.length() - 1];
// return (int)(digit1 - digit2);
}
};
Collections.sort(list, myComparator);
// or
Arrays.sort(array, myComparator);
So you are letting someone else's sort method do the sorting for you, you just need to provide a method to say how to compare the items. There are some rules and regulations you need to stick to (e.g. if A < B, B < C then A must be < C).
You can also do it inline/anonymously:
Collections.sort(list, new Comparator<String>() {
public int compare(String s1, String s2) {
...
}
});
Related
My array is expected to have elements that look like "B1" and "C22" for any letter A-Z and number 1-26.
I need to sort this array numerically, so we don't consider the first character of the string when sorting. So that an array {"B1", "A22", "C9"} would be sorted to {"B1", "C9", "A22"}.
I have tried to take a substring, but it doesn’t work since I don’t know which strings will be of length 3 and which will be of length 2.
You can create your own comparator that ignores some of the characters :
Arrays.sort(s, new MyComparator());
System.out.println(Arrays.toString(s));
class MyComparator implements Comparator<String> {
#Override
public int compare(String o1, String o2) {
// Remove the chars you are want to ignore from o1, o2
o1 = o1.substring(1);
o2 = o2.substring(1);
return Integer.compare(Integer.parseInt(o1),Integer.parseInt(o2));
// return o1.compareTo(o2); see petr note bellow
}
}
If the array contains a huge number of elements, then you can replace Arrays.sort() with Arrays.parallelSort() to sort efficiently.
Arrays.sort(arr,
(ele1, ele2) -> ele1.substring(1).compareTo(ele2.substring(1)));
if you are confident that substring(1) only contains numeric value, then you can sort as below:
Arrays.sort(arr, (Comparator.comparingInt(element ->
Integer.parseInt(element.substring(1)))));
I need some help in JAVA:
I have a function signature which I can't change, and my function needs to be recursive and to return String array without any option to add it to the signature.
This is the signature I've got:
public String[] findSimilar(String w, int index, int k)
The function looks for similar words in a TRIE structure, with a difference of K letters changes between them.
For example- in a TRIE withe the words hello, nice, nine, cry, for the word "bike" and k=2, the function will return a String[] with nice and nine.
I'm not looking for a solution, just for a method to return string array.
** I wrote a function with the signature I've received as a wrapper, but I just found out that I can't use wrapper.
Thank you!
The trivial example:
public String[] findSimilar(String w, int index, int k) {
return new String[] {"string1","string2"}
}
Maybe more useful:
public String[] findSimilar(String w, int index, int k) {
List<String> similar = new ArrayList<>();
// insert some implementation here
return similar.toArray(new String[similar.size()]);
}
I'm not looking for a solution, just for a method to return string array.
To return a string array with literals string1 and string2 you could just use an array initializer such as return new String[] { "string1", "string2"};
Else, you could just create the String array and assign values to its positions if you know beforehand how many elements you will be returning:
String[] arr = new String[2];
arr[0] = "string1";
arr[1] = "string2";
return arr;
If it's the return type of a recursive function, you'll probably need to use the result from the recursive call to build your own result in the current call. Taking into account arrays cannot be extended, you'll need to create a new one with the expected size, and copy the values of the result into it for instance with System.arraycopy.
Use something like this.
I would not like to provide full code just an idea
public String[] findSimilar(String w, int index, int k) {
String[] res1=findSimilar(conditions one);
String[] res2=findSimilar(conditions two);
String[] res=new String[res1.length+res2.length];
//use public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
System.arraycopy(copyFrom, ..., copyTo, ..., ...);
}
I have a multidimensional array with double values that I would like to sort..
//declare array
standingsB = new Double[10][2];
//populate array from the temparray created during read from file
arryLgt = 0;
for (int row = 0; row < standingsB.length; row++){
for (int column = 0; column < standingsB[row].length; column++) {
standingsB[row][column] = Double.parseDouble(tempStandingsArray[arryLgt]);
arryLgt = arryLgt + 1;
}
}
The array has values such as [1.5,7.0] [4.2,4.0] etc...
For the next part I don't really know how it works but from reading other articles here this is the best as I can copy without knowledge
Arrays.sort(standingsB, new Comparator<Double[]>() {
#Override
public int compare(Double[] s1, Double[] s2) {
compare(s1, s2);
}
});
The above fails to compile (with missing return statement) which is to be expected as I have no idea on how to use the Arrays.sort with a comparator. But I'm not even sure if I'm on the right page being as new to Java (and programing in general) as I am.
Thanks for looking!
You're pretty close. Your comparator will depend on what order you want your results in. Let's say you want the rows to be sorted in the natural order of the first element in each row. Then your code would look like:
Arrays.sort(standingsB, new Comparator<Double[]>() {
public int compare(Double[] s1, Double[] s2) {
if (s1[0] > s2[0])
return 1; // tells Arrays.sort() that s1 comes after s2
else if (s1[0] < s2[0])
return -1; // tells Arrays.sort() that s1 comes before s2
else {
/*
* s1 and s2 are equal. Arrays.sort() is stable,
* so these two rows will appear in their original order.
* You could take it a step further in this block by comparing
* s1[1] and s2[1] in the same manner, but it depends on how
* you want to sort in that situation.
*/
return 0;
}
}
};
I think the answer provided by #Tap doesn't fulfill the askers question to 100%. As described, the array is sorted for its value at the first index only. The result of sorting {{2,0},{1,2},{1,1}} would be {{1,2},{1,1},{2,0}} not {{1,1},{1,2},{2,0}}, as expected. I've implemented a generic ArrayComparator for all types implementing the Comparable interface and released it on my blog:
public class ArrayComparator<T extends Comparable<T>> implements Comparator<T[]> {
#Override public int compare(T[] arrayA, T[] arrayB) {
if(arrayA==arrayB) return 0; int compare;
for(int index=0;index<arrayA.length;index++)
if(index<arrayB.length) {
if((compare=arrayA[index].compareTo(arrayB[index]))!=0)
return compare;
} else return 1; //first array is longer
if(arrayA.length==arrayB.length)
return 0; //arrays are equal
else return -1; //first array is shorter
}
}
With this ArrayComparator you can sort multi-dimensional arrays:
String[][] sorted = new String[][]{{"A","B"},{"B","C"},{"A","C"}};
Arrays.sort(sorted, new ArrayComparator<>());
Lists of arrays:
List<String[]> sorted = new ArrayList<>();
sorted.add(new String[]{"A","B"});
sorted.add(new String[]{"B","C"});
sorted.add(new String[]{"A","C"});
sorted.sort(new ArrayComparator<>());
And build up (Sorted)Maps easily:
Map<String[],Object> sorted = new TreeMap<>(new ArrayComparator<>());
sorted.put(new String[]{"A","B"}, new Object());
sorted.put(new String[]{"B","C"}, new Object());
sorted.put(new String[]{"A","C"}, new Object());
Just remember, the generic type must implement the Comparable interface.
Solution with lambda sorting array of int[][] contests example :
Arrays.sort(contests, (a, b)->Integer.compare(b[0], a[0]));
Arrays.sort() expects a single dimensional array while in your case you are trying to pass a multidimensional array.
eg
Double[] d = {1.0,5.2,3.2};
Then you use Arrays.sort(d) since the sort can work on the primitive types or the wrapper types.
All I need is the simplest method of sorting an ArrayList that does not use the in-built Java sorter. Currently I change my ArrayList to an Array and use a liner sorting code, but I later need to call on some elements and ArrayLists are easier to do that.
you can use anonymous sort.
Collections.sort(<ArrayList name>, Comparator<T>() {
public int compare(T o1, T o2) {
.....
....
}
});
where T is the type you want to sort (i.e String, Objects)
and simply implement the Comparator interface to your own needs
Assuming an ArrayList<String> a...
Easiest (but I'm guessing this is what you're saying you can't use):
Collections.sort(a);
Next easiest (but a waste):
a = new ArrayList<String>(new TreeSet<String>(a));
Assuming "in-built sort" refers to Collections.sort() and you are fine with the sorting algorithm you have implemented, you can just convert your sorted array into an ArrayList
ArrayList list = new ArrayList(Arrays.asList(sortedArray));
Alternatively, you can rewrite your sorting algorithm to work with a List (such as an ArrayList) instead of an array by using the get(int index) and set(int index, E element) methods.
Sorting Arguments passed through Command prompt; without using Arrays.sort
public class Sort {
public static void main(String args[])
{
for(int j = 0; j < args.length; j++)
{
for(int i = j + 1; i < args.length; i++)
{
if(args[i].compareTo(args[j]) < 0)
{
String t = args[j];
args[j] = args[i];
args[i] = t;
}
}
System.out.println(args[j]);
}
}
}
By using Array.sort
import java.util.*;
public class IntegerArray {
public static void main(String args[])
{
int[] num=new int[]{10, 15, 20, 25, 12, 14};
Arrays.sort(num);
System.out.println("Ascending order: ");
for (int i=0; i<num.length; i++)
System.out.print(num[i] + " ");
}
}
Collections.sort(List);
If i remember correctly when you pull an element out of the middle of an arrayList it moves the rest of the elements down automaticly. If you do a loop that looks for the lowest value and pull it out then place it at the end of the arrayList. On each pass i-- for the index. That is use one less. So on a 10 element list you will look at all 10 elements take the lowest one and append it to the end. Then you will look at the first nine and take the lowest of it out and append it to the end. Then the first 8 and so on till the list is sorted.
Check for Comparator in java. You can implement your own sorting using this and use Collections.sort(..) to sort the arraylist using your own Comparator
If you are meant to sort the array yourself, then one of the simplest algorithms is bubble sort. This works by making multiple passes through the array, comparing adjacent pairs of elements, and swapping them if the left one is larger than the right one.
Since this is homework, I'll leave it to you to figure out the rest. Start by visualizing your algorithm, then think about how many passes your algorithm needs to make, and where it needs to start each pass. Then code it.
You also need to understand and solve the problem of how you compare a pair of array elements:
If the elements are instances of a primitive type, you just use a relational operator.
If the elements are instances of reference types, you'll need to use either the Comparable or Comparator interface. Look them up in the javadocs. (And looking them up is part of your homework ...)
Here is a "simple" quicksort implementation:
public Comparable<Object>[] quickSort(Comparable<Object>[] array) {
if (array.length <= 1) {
return array;
}
List<Comparable<Object>> less = new ArrayList<Comparable<Object>>();
List<Comparable<Object>> greater = new ArrayList<Comparable<Object>>();
Comparable<Object> pivot = array[array.length / 2];
for (int i = 0;i < array.length;i++) {
if (array[i].equals(pivot)) {
continue;
}
if (array[i].compareTo(pivot) <= 0) {
less.add(array[i]);
} else {
greater.add(array[i]);
}
}
List<Comparable<Object>> result = new ArrayList<Comparable<Object>>(array.length);
result.addAll(Arrays.asList(quickSort(less.toArray(new Comparable<Object>[less.size()]))));
result.add(pivot);
result.addAll(Arrays.asList(quickSort(greater.toArray(new Comparable<Object>[greater.size()]))));
return result.toArray(new Comparable<Object>[result.size()]);
}
The last operations with arrays and list to build the result can be enhanced using System.arraycopy.
I have a two dimensional array that is holding the value of 5 cards. The first element of each of the 5 arrays represents the suit of the card, and the second element represents the card value.
I want to sort the 2d array by the second element, and then by the first element while maintaining the sorted order of the second element (if that makes sense). For example all suits of ones will be lower on the sorted list than all suits of two. So for example, {{0,1},{2,1},{0,2}} should become {{0,1},{2,1},{0,2}}.
Here is what I have:
// {{3,2}, {2,2}, {0,1}, {1,0}, {2,3}} should become
// {{1,0}, {0,1}, {2,2}, {3,2}, {2,3}}
int[][] hand = {{3,2},{2,2},{0,1},{1,0},{2,3}};
sort(hand);
public static void sort(int[][] hand){
Arrays.sort(hand, new Comparator<int[]>(){
public int compare(int[] o1, int[] o2){
return Integer.valueOf(o1[1]).compareTo(Integer.valueOf(o2[1]));
}
});
}
This is outputting {{1,0},{0,1},{3,2},{2,2},{2,3}}. Does anyone have any suggestions?
Solution 1: sort the arrays by the second element, and then sort the arrays by the first element. Since Arrays.sort is stable, that's equivalent to first comparing by the first element, then the second.
Solution 2: modify your comparator as follows:
Arrays.sort(hand, new Comparator<int[]>() {
public int compare(int[] o1, int[] o2) {
if (o1[0] == o2[0]) {
return Integer.compare(o1[1], o2[1]);
} else {
return Integer.compare(o1[0], o2[0]);
}
}
});
or, with Guava (disclosure: I contribute to Guava), you can just write the comparator as
public int compare(int[] o1, int[] o2) {
return ComparisonChain.start()
.compare(o1[0], o2[0])
.compare(o1[1], o2[1])
.result();
}
Would this work for you:
int compare1 = Integer.valueOf(o1[1]).compareTo(Integer.valueOf(o2[1]);
if(compare1 != 0)
return compare1;
else
return Integer.valueOf(o1[0]).compareTo(Integer.valueOf(o2[0]));
I will add a Java 8 solution, just in case someone wants to know.
Arrays.sort(hand, (o1, o2) -> o1[1] == o2[1] ? Integer.compare(o1[0], o2[0])
: Integer.compare(o1[1], o2[1]));
Basically, it compares the first element of each array when second element is equal, otherwise just compare the second elements directly.
You can use Java 8 Comparator in a more compact way like this
Arrays.sort(hand, Comparator.comparing(x -> ((int[])x)[1]).thenComparing(x -> ((int[])x)[0]));