Android array sorting - java

I have an array ordered in alphabetical order;
[0] = apple
[1] = banana
[2] = mango
[2] = melon
What I need to do now, Is split the string array into smaller string arrays with groups of the letters, so the output would be:
[0] = apple
[0] = banana
[0] = mango
[1] = melon
I've tried a few methods, but all of them are hopeless, Can you give me a piece of code that will do this? I promise to give the best answer a tick and all the good answers a point!

Here's how I would do :
create a sorted map (for example a TreeMap) with the first char as key, and a list of fruits as value
iterate through the original array.
at each iteration, extract the first char and see if the map contains it as a key. If not, create an empty list of fruits, and put it in the map. Put the current fruit in the list (whether it was already in the map or not)
Ask for the values of the map : it's an ordered collection of fruit lists. transforming it into an array of arrays is trivial with Collection.toArray.

Here is a simple but not thoroughly optimized example. Also I'm not sure how this will fare with multi-byte first characters as in Umlauts etc.
public static void sortByFirstChar() {
String[] array = new String[4];
array[0] = "apple";
array[1] = "banana";
array[2] = "mango";
array[3] = "melon";
HashMap<Character, ArrayList<String>> charToList = new HashMap<Character, ArrayList<String>>();
for (String item : array) {
char firstChar = item.charAt(0);
if (charToList.containsKey(firstChar)) {
charToList.get(firstChar).add(item);
} else {
ArrayList<String> list = new ArrayList<String>();
list.add(item);
charToList.put (firstChar, list);
}
}
Set<Character> keySet = charToList.keySet();
for (char key : keySet) {
// Here are the arrays
System.out.println("Items for char " + new Character((char)key).toString() + ":");
for (String item : charToList.get(key)) {
System.out.println (" " + item);
}
}
}
Sample output:
Items for char b:
banana
Items for char a:
apple
Items for char m:
mango
melon

You will definitely want to use a better way to store the data instead of arrays... maybe a TreeMap or just a List of strings:
String[] arr = new String[]{"apple", "banana", "mango", "melon"};
List<List<String>> arrs = new ArrayList<List<String>>();
char f = 0;
List<String> last = null;
for(String s : arr){
if( f != s.charAt(0) ){
f = s.charAt(0);
// since first the char is different, create a new array
last = new ArrayList<String>();
last.add(s);
if( last != null ){
arrs.add(last);
}
}
else {
last.add(s);
}
}
In the case above, you will have a List of Lists of strings (arrs). Good thing about lists is that their size is dynamic (arrays dimensions are static).

Here's an UNOPTIMIZED solution. I tested for a few different combos. The output is list of arrays. The printList function prints the array in logCat you might want to replace it with your own function:
public class SortArray extends Activity {
ArrayList matchedFruits = new ArrayList();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String fruits[] = new String[7];//Sorted array
fruits[0] = "apple";
fruits[1] = "apricot";
fruits[2] = "banana";
fruits[3] = "mango";
fruits[4] = "melon";
fruits[5] = "pineapple";
fruits[6] = "peach";
char currChar=fruits[0].charAt(0);//Get first char of first element
boolean match=false;
int len=fruits.length;
List tmp = new ArrayList();
for(int i=1;i < len;i++)
{
Log.d("Comparing ", fruits[i].charAt(0)+","+currChar);
if (fruits[i].charAt(0)==currChar)
{
if (match==false)//new match?
{
match=true;//Reset search
tmp.clear();//clear existing items
tmp.add(fruits[i-1]);
Log.d("Started new list ", fruits[i-1]);
}
else
{
tmp.add(fruits[i-1]);
Log.d("Added to list ", fruits[i-1]);
}
}
else
{
match=false;
tmp.add(fruits[i-1]);
matchedFruits.add(tmp.toArray(new String[tmp.size()]));//add to final list
Log.d("Finished a list ", fruits[i-1]);
tmp.clear();//clear existing items
}
currChar=fruits[i].charAt(0);
}
tmp.add(fruits[len-1]);
matchedFruits.add(tmp.toArray(new String[tmp.size()]));//add left over items
printList();
}
void printList()
{
//Print the list
for(int i=0;i < matchedFruits.size();i++)
{
String tmp2[]= matchedFruits.get(i);
for (int j=0;j < tmp2.length;j++)
{
Log.d("Final list", "Array #"+i+"["+j+"],"+tmp2[j]);
}
}
}
}

Related

Delete method without built in functions

here is my code and I need to remove a fruit from the array
public void delete(String fruitName) {
for (int i = 0; i < fruits.length; i++) {
if ( fruits[i].equals(fruitName)) {
fruits[i] = fruits[i+1];
break;
}
}
// ["banana", "apple, "Mango"] if removed banana then output ["apple", "Mango"].
// TODO: 1. implement this method.
/* TODO: 2. you may need to consult Java API documentation for the String class.
* Write a comment in the code, the method of the String class you
* look up and the URL to the documentation the method
*/
}
"Working code Example : "(Execution)
public class DeleteValue {
String fruits[] = { "apple", "orange", "banana", "mango", "Cherries", "Blueberries" }; // array of fruits
public void delete(String fruitName) {
// printing array of fruits before deletion
System.out.println("\nAvailable fruits Before delete : " + fruits.length + "\n");
for (String s : fruits) {
System.out.println(s + " is Available\n");
}
int length = fruits.length;
int lengthNew = length;
int countNull = 0;
// 1. Find and delete the fruit
for (int i = 0; i < fruits.length; i++) {
if (fruits[i] == fruitName) {
fruits[i] = null;
break;
}
}
// count the null or deleted values so that we can create a new array of length
// minus the deleted fruit
for (int i = 0; i < fruits.length; i++) {
if (fruits[i] == null) {
countNull++;
}
}
// new array length
lengthNew = lengthNew - countNull;
// create new array of fruits
String newFruits[] = new String[lengthNew];
// assigning values from original array to new
int j = 0;
for (int i = 0; i < fruits.length; i++) {
if (fruits[i] == null) {
continue;
}
if (fruits[i] != null) {
newFruits[j] = fruits[i];
j++;
}
}
System.out.println("------------------------------------------");
System.out.println("\nAvailable fruits after delete : " + newFruits.length + "\n");
// print the final output
for (String s : newFruits) {
System.out.println(s + " is Available\n");
}
}
public static void main(String args[]) {
new DeleteValue().delete("mango");
;
}
}
Explanation :
The only Issue I am having its that Fruit Array is not decreasing the
size
An array is a container object that holds a fixed number of values of a single type. The length of an array is established when the array is created. After creation, its length is fixed
So what we can do is either use a dynamic array or we can use a work around like the above code:
If you want to "grow" or "shrink" an existing array, you have to allocate a new array of the appropriate size and copy the array elements from old array to the new array.
In the above code I have provided comments for the working steps.
We are solving this problem is three steps:
Find and delete the fruit item from array.
count the deleted values from old array so that we can create a new array
of that size.
Move all remaining items from old array to new array.

To print the first biggest and second biggest elements in a string

Below is the code I have implemented. My doubt here is: when I am trying to print the first biggest and second Biggest values in the string, the output I get is in the order of [second biggest, first biggest].
Here is the output of what I got for the below code:
The output of the map is: real--6
The output of the map is: to--2
The output of the map is: world--1
The output of the map is: hello--0
The list after insertion is: [to, real]
The list inserted as [biggest,secondBiggest] after calling main is: [to, real]
......
but, I want The list after insertion to be: [real, to].
public class ReadString {
static String input = "This is a real project with real code to do real things to solve real problems in real world real";
public static void main(String[] args) {
List<String> lst = ReadString.RepeatedString("This is a real project with real "
+ "code to do real things to solve real " + "problems in real world real");
System.out.println("The list inserted as [biggest,secondBiggest] after calling main is: " + lst);
}
public static List<String> RepeatedString(String s) {
String[] s2 = input.split(" ");
String[] key = { "real", "to", "world", "hello" };
int count = 0;
Integer biggest = 0;
Integer secondBiggest = 1;
Map<String, Integer> map = new HashMap<String, Integer>();
for (int j = 0; j < key.length; j++) {
count = 0;
for (int i = 0; i < s2.length; i++) {
if (s2[i].equals(key[j])) {
count++;
}
}
map.put(key[j], count);
System.out.println("The output of the map is: " +key[j] + "--" + count);
}
/*
* To find the top two most repeated values.
*/
List<Integer> values = new ArrayList<Integer>(map.values());
Collections.sort(values);
for (int n : map.values()) {
if (biggest < n) {
secondBiggest = biggest;
biggest = n;
} else if (secondBiggest < n)
secondBiggest = n;
}
/* To get the top most repeated strings. */
List<String> list = new ArrayList<String>();
for (String s1 : map.keySet()) {
if (map.get(s1).equals(biggest))
list.add(s1);
else if (map.get(s1).equals(secondBiggest))
list.add(s1);
}
System.out.println("The list after insertion is: " +list);
return list;
}
}
The problem appears to be when you are adding items to the list. As you are iterating through the map.keySet(), there is no guarantee that you will get the biggest item first. The smallest change I would make would be to add the biggest item first in the list.
for (String s1 : map.keySet()) {
if (map.get(s1).equals(biggest))
list.add(0, s1);
else if (map.get(s1).equals(secondBiggest))
list.add(s1);
}
This way, if secondBiggest is added first, biggest will be at the top of the list.
We can simplify your approach quite a bit if we extract the word and count into a simple POJO. Something like,
static class WordCount implements Comparable<WordCount> {
String word;
int count;
WordCount(String word, int count) {
this.word = word;
this.count = count;
}
#Override
public int compareTo(WordCount o) {
return Integer.compare(count, o.count);
}
}
Then we can use that in repeatedString. First, count the words in the String; then build a List of WordCount(s). Sort it (since it's Comparable it has natural ordering). Then build the List to return by iterating the sorted List of WordCount(s) in reverse (for two items). Like,
static List<String> repeatedString(String s) {
Map<String, Integer> map = new HashMap<>();
for (String word : s.split("\\s+")) {
map.put(word, !map.containsKey(word) ? 1 : 1 + map.get(word));
}
List<WordCount> al = new ArrayList<>();
for (Map.Entry<String, Integer> entry : map.entrySet()) {
al.add(new WordCount(entry.getKey(), entry.getValue()));
}
Collections.sort(al);
List<String> ret = new ArrayList<>();
for (int i = al.size() - 1; i >= al.size() - 2; i--) {
ret.add(al.get(i).word);
}
return ret;
}
Finally, your main method should use your static input (or static input should be removed)
static String input = "This is a real project with real code to do "
+ "real things to solve real problems in real world real";
public static void main(String[] args) {
List<String> lst = repeatedString(input);
System.out.println("The list inserted as [biggest,"
+ "secondBiggest] after calling main is: " + lst);
}
And I get (as requested)
The list inserted as [biggest,secondBiggest] after calling main is: [real, to]
If you are only concerned about biggest and secondbiggest,
you can refer to the code below.
Instead of creating the list directly, I created an array, added required elements on specified positions. (This way it becomes more readable)
and finally convert the array to a list.
/* To get the top most repeated strings. */
String[] resultArray = new String[2];
for (String s1 : map.keySet()) {
if (map.get(s1).equals(biggest))
resultArray[0]=s1;
else if (map.get(s1).equals(secondBiggest))
resultArray[1]=s1;
}
List<String> list = Arrays.asList(resultArray);

How to find index of ArrayList item in String Array

I want to find ArrayList<String> item's index in String Array but every time indexOf() give -1 index .
I cant understand where is wrong? Please check my code and guide me.
public static void arrangeUiComponent() {
ArrayList<String> packageName = new ArrayList<String>();
packageName.add("com.example.dummy");
packageName.add("edu.app.reading");
ArrayList<Integer> index = getIndex(packageName);
}
// searching method
private static ArrayList<Integer> getIndex(ArrayList<String> searchName) {
ArrayList<Integer> indexList = new ArrayList<Integer>();
String[] collectionData = new String[] { "com.example.app",
"com.example.appdemo", "com.example.dummy", "edu.app.reading",
"edu.app.knowledge" };
/*
* for iterating each and every item of list
*/
for (int i = 0; i < searchName.size(); i++) {
Log.i("MISSION", "value will be: " + searchName.get(i).toString());
/*
* for searching listItem in package name array
*/
for (int j = 0; j < collectionData.length; j++) {
indexList.add(collectionData.toString().indexOf(searchName.get(i).toString()));
break;
}
}
return indexList;
}
Replace
for (int j = 0; j < collectionData.length; j++) {
indexList.add(collectionData.toString().indexOf(searchName.get(i).toString()));
break;
}
with
indexList.add(Arrays.asList(collectionData).indexOf(searchName.get(i)));
Here is the working demo of your code. Arrays.asList converts your string array to a list. Why don't you use a list instead of string collectionData array?
Use a debugger and look the value of collectionData.toString().
It returns something that is not your list of strings. That the object representation.
Quote from javadoc:
The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `#', and the unsigned hexadecimal representation of the hash code of the object.
EDIT:
whoops, collectionDatais an array, not a List, you should use
java.util.Arrays.asList(collectionData).indexOf(searchName.get(i))
It will search for the searchName.get(i)string inside the collectionDataList and not inside the collectionData representation which is a String (that's why indexOf is valid).
As searchName is a list of String, you don't need to add the toString() on searchName.get(i)
I'm assuming that in the indexLIst you want corresponding packageName's index values.
I don't think this will work in the way you want it.
The indexList being an Arraylist(data is not stored in the input order) might not have corresponding index values.
Ex:
packageName list:
"com.example.dummy", "edu.app.reading"
so the indexList should have values:
2 , 3
but it might contain:
3, 2 as well because data is not stored in the order in which it is entered.
You should probably use a linkedList if you want to preserve the order.
use a Hashmap<String, integer>.
You can do something like this using a hashmap:
public static void arrangeUiComponent() {
ArrayList<String> packageName = new ArrayList<String>();
packageName.add("com.example.dummy");
packageName.add("edu.app.reading");
HashMap<String, Integer> indexMap = getIndex(packageName);
for (String s : packageName) {
int index = indexMap.get(s);
}
}
private static HashMap<String, Integer> getIndex(ArrayList<String> searchName) {
HashMap<String, Integer> indexMap = new HashMap<String, Integer>();
String[] collectionData = new String[] { "com.example.app", "com.example.appdemo", "com.example.dummy",
"edu.app.reading", "edu.app.knowledge" };
for (String search : searchName) {
for (int i = 0; i < collectionData.length; i++) {
if (search.equals(collectionData[i])) {
indexMap.put(search, i);
break;
}
}
}
return indexMap;
}
You use collectionData.toString() which return [Ljava.lang.String;#15db9742. So collectionData.toString().indexof() always find nothing and return -1
To solve this you can use:
Declare arraylist as
ArrayList<String>cd = new ArrayList<String>(Arrays.asList(collectionData));
which convert String[] to ArrayList then ArrayList gives us facility of finding element with indexof().
Then in your inner for loop
for (int j = 0; j < collectionData.length; j++) {
indexList.add(cd.indexOf(searchName.get(i).toString()));
break;
}
toString() method of an array returns something similar to [Ljava.lang.String;#2a139a55. This is the reason you were getting index value as -1.
Other than the solution sam2090 provided, you can try 2 more options.
Replace
indexList.add(collectionData.toString().indexOf(searchName.get(i).toString()))
with
indexList.add(java.util.Arrays.binarySearch(collectionData, searchName.get(i)))
or
Replace collectionData.toString() with java.util.Arrays.toString(values)

parse array and extract string of same length

my first question.
lets say i have arraylist of strings in java
ArrayList<string> s= new ArrayList<string>;
and it contains sorted list by size.
s.add("ab");
s.add("abc");
s.add("aab");
s.add("baab");
s.add("abcd");
what i want to do is, iterate the list and pick group of elements which has same length and put into seprate array of arrays.
Group 1 ab
Group 2 abc,aab and so on...
i am doing this in java please help
Since they're sorted by size already it's easy. Here's one way that works:
ArrayList<ArrayList<String>> listofLists = new ArrayList<ArrayList<String>>();
int length = -1;
for(String str : s) { // where s is your sorted ArrayList of Strings
if(str.length() > length) {
listofLists.add(new ArrayList<String>());
length = str.length();
}
listofLists.get(listofLists.size()-1).add(str);
}
At the end, listofLists will be an ArrayList of ArrayLists containing groups of Strings of the same length. Again, this depends on s (your ArrayList<String>) being sorted by size. Also, String must be capitalized there.
You can use this code "it works as you need"
import java.util.ArrayList;
public class Test{
public static void main(String[] args){
ArrayList<String> s = new ArrayList<String>();
s.add("ab");
s.add("abc");
s.add("aab");
s.add("baab");
s.add("abcd");
String[] group1 = new String[s.size()];
String[] group2 = new String[s.size()];
String[] group3 = new String[s.size()];
for(int i = 0 ; i < s.size() ; i++){
if(s.get(i).length() == 2)
group1[i] = s.get(i);
else if(s.get(i).length() == 3)
group2[i] = s.get(i);
else
group3[i] = s.get(i);
}
for(String ss : group1){
if(ss == null)
break;
System.out.println(ss);
}
System.out.println();
for(String ss : group2){
if(ss == null)
continue;
System.out.println(ss);
}
System.out.println();
for(String ss : group3){
if(ss == null)
continue;
System.out.println(ss);
}
}
}
I hope it useful for you.

Sort String "13,5,8,4,2,1,9" in ascending order 1,2,4,5,8,9,13 in Java

How can I sort a string "13,5,8,4,2,1,9" in ascending order, to get 1,2,4,5,8,9,13?
Split the string by commas
Parse each substring into an integer
Sort the resulting collection
If you need the result to be a string (it's not clear), convert each integer back into a string and join them together with commas.
If any of those steps causes you difficulties, please be more specific.
Split it into an array of items with String.split().
Convert to an array of numbers with Integer.valueOf().
Sort the array.
Concatenate it all back into a StringBuilder.
As one liner, using Google Collections (updated with Kevin's suggestion)
Joiner.on(",").join(Ordering.natural().onResultOf(new Function<String, Integer>() {
#Override
public Integer apply(String from) {
return Integer.valueOf(from);
}
}).sortedCopy(Arrays.asList("4,2,7,9,1".split(","))));
Split using String.split()
Transform to Integer using a Function (anyone know if there's a constant for this one somewhere?)
Sort using a TreeSet and natural ordering
Join the parts and transform back to a String using Joiner
(old version)
Joiner.on(',').join(
Sets.newTreeSet(
Iterables.transform(
Arrays.asList("13,5,8,4,2,1,9".split(",")),
new Function<String, Integer>() {
#Override
public Integer apply(String from) {
return Integer.parseInt(from);
}}))));
String s = "13,5,8,4,2,1,9";
String[] arr = s.split(",");
Arrays.sort(arr, new Comparator<String>() {
#Override public int compare(String s1, String s2) {
return Integer.parseInt(s1) - Integer.parseInt(s2);
}
});
s = Arrays.toString(arr).replaceAll("[\\[ \\]]", "");
This solution uses:
java.util.Comparator
java.util.Arrays sort and toString
String split and replaceAll
regular expression
I would tokenize the string using StringTokenizer,
parse the values (using Integer.parseInt),
then sort the results using Arrays.sort.
Lastly, re-create the string.
String str = "13,5,8,4,2,1,9";
StringTokenizer tokens = new StringTokenizer(", ");
ArrayList<Integer> ints = new ArrayList<Integer>();
for(String token: tokens)
ints.add(Integer.parseInt(token));
Collection.sort(ints);
String sortedStr = "";
for(int i = 0; i + 1 < ints.size(); ++i)
sortedStr += ints.get(i) + ", ";
if (ints.size() > 0)
sortedStr += ints.lastElement();
Might have some misspellings, but I think not. Also, add the appropriate imports yourself =)
So you have a string containing a comma-delimited set of integers that you need to sort and then output to a string? Try split-ting the string, parse-ing the integers, sort-ing the resulting array, and then join-ing the results together
Java 8+
If you are using Java 8 you can use streams to sort like so :
String str = "13,5,8,4,2,1,9";
String sortedString =
Arrays.stream(str.split(",")) //split with ','
.map(Integer::valueOf) //convert your strings to ints
.sorted() //sort
.map(String::valueOf) //convert them back to string
.collect(Collectors.joining(","));//1,2,4,5,8,9,13
If you want an sorted array you can also use :
Integer[] sortedInts =
Arrays.stream(str.split(",")) //split with ','
.map(Integer::valueOf) //convert your strings to ints
.sorted() //sort
.toArray(Integer[]::new);//[1, 2, 4, 5, 8, 9, 13]
The idea is the same as Jon Skeet explanation.
An alternative using java.util.Scanner
public class SortString {
public static void main( String [] args ) {
// Read integers using Scanner...
Scanner scanner = new Scanner( "13,5,8,4,2,1,9" ).useDelimiter(",");
// Put them in a Integer list
List<Integer> list = new ArrayList<Integer>();
while( scanner.hasNextInt() ){
list.add( scanner.nextInt() );
}
// And sort it
Collections.sort( list );
System.out.println( list );
}
}
ok you can try this one it work in all case.
package com.java;
import java.util.*;
public class cd
{
public static void main(String s[])
{
Collections col;
List l = sort(s);
System.out.println("\nStrings sorted List ...");
for(int i = 0; i < s.length; i++)
{
System.out.println((String)l.get(i));
}
int ints[] = {
719, 2, -22, 401, 6
};
Integer in[] = new Integer[ints.length];
for(int i = 0; i < in.length; i++)
{
in[i] = new Integer(ints[i]);
}
l = sort(in);
System.out.println("\nIntegers sorted List ...");
for(int i = 0; i < in.length; i++)
{
System.out.println((Integer)l.get(i));
}
}
public static List sort(Object o[])
{
ArrayList al = new ArrayList();
for(int i = 0; i < o.length; i++)
al.add(i, o[i]);
List list = Collections.synchronizedList(al);
Collections.sort(list);
return list;
}
}
This is one way to sorting.
package com.java;
import java.util.ArrayList;
import java.util.Collections;
public class b{
public static void main(String[] args) {
//create an ArrayList object
ArrayList arrayList = new ArrayList();
//Add elements to Arraylist
arrayList.add("9");
arrayList.add("3");
arrayList.add("5");
arrayList.add("2");
arrayList.add("4");
Collections.sort(arrayList);
//display elements of ArrayList
System.out.println("ArrayList elements after sorting in ascending order : ");
for(int i=0; i<arrayList.size(); i++)
System.out.println(arrayList.get(i));
}
}
class SplitStr
{
public static void main(String args[])
{
try
{
String str=args[0]+","+args[1]; //marge two string in one
String sArr[]=str.split(",");
int slen=sArr.length;
int iArr[]=new int[slen];
int temp;
for(int i=0;i<slen;i++)
{
iArr[i]=Integer.parseInt(sArr[i]); //convert String into integer array
}
for(int i=0;i<slen;i++)
{
for(int j=i+1;j<slen;j++)
{
if(iArr[i]>=iArr[j])
{
temp=iArr[i];
iArr[i]=iArr[j];
iArr[j]=temp;
}
}
}
for(int i=0;i<slen;i++)
{
System.out.println(" "+iArr[i]);
}
}
catch(Exception e)
{
System.out.println("input error "+e);
}
}
}
Bash is SO powerful :-)
numbers="1, 2, 9, 4, 7, 5" ; for number in $(echo "$numbers") ; do echo "$number" | tr -d ", "; done | sort | tr "\n" "," ; echo ""

Categories

Resources