Finding index of duplicate values in an ArrayList - java

I have an ArrayList which contains duplicate values at diff diff index.
for example {"Indian","American","Chinese","Australian","Indian","Russian","Indian"}
as u can see the value - "Indian" exists at index - 0, 4 & 6.
I need to know all these indexes where "Indian" exists and create an arrayList of that.
Here is my code:
public void filter(){
categoryArray = Arrays.asList(category);
for(String k : category){
//Log.v("filter", filterTerm);
if(k.equals(filterTerm.toLowerCase()))
{
int p = categoryArray.indexOf(k);
Log.v("index of categArr", ""+p);
String id = Integer.toString(p);
indexes.add(id);
}// end of if
}// end of for
Here I get how many times duplicate occurs by getting the size of indexes(ArrayList)
but when I check the values . Its one value at all index since in the method : indexOf() it always brings the index of first value that it finds in the Array.
So if duplicate exists at index - 2,5,7
I get the array size of index as 3.
But the values are {2,2,2,};

This is a situation where an index-based for loop is more appropriate than enhanced for loop that you're using, as what you need to grab is the index.
You can base all your work on the original array rather than converting it to a list, and I suspect you were going for case-insensitive match.
public void filter(){
for(int i=0; i<category.length; i++){
if(category[i].equalsIgnoreCase(filterTerm))
{
String id = Integer.toString(i);
indexes.add(id);
}
}
}
If you have an ArrayList rather than an array, of course similar code will work, but using list.get(i) instead of category[i].

You need to know which index in the array you are currently at, not the first index where it is to be found. To keep track of that, put
int i = 0;
before the loop, and at the very end of the loop put
i++;
Then the variable i tells you where you have found the value, so you can add i to the indexes list.

Related

Adding elements dynamically in String array but index 0 showing null?

I want to add some values in string array dynamically by using for loop.
when i debug the code at first for loop it is showing values which are adding.I want to check if any one of the string equals to my given value.but in for loop 2 at index 0 it showing null and at index 1 it showing the string value.
for(int i=0;i<someval;i++) {
String[] mylist = new String[someval];
mylist[i]=previousVal;
System.out.println("Previous Value : " +mylist[i]);
}
for (int j = 0; j <=mylist.length; j++) {
if (mylist[j].equals(givenValue) ) { {
System.out.println("your value found in the array");
}
}
The problem is that you are creating a new array using
mylist = new String...
during each loop iteration.
So, it doesn't really matter if you write something to an array, if the next step consists of throwing that array away.
In other words: make sure that you create the array just once; preferable before entering your loop.

Arraylist - Using switch statement to add string

I am new to programming and my professor has given an assignment that requires us to:
"declare on arraylist with the size of 5. Use switch statement to add string values to your arraylist. Retrieve the contents of your arraylist. Check the size of each element. If the element length is less than 8 rerun the program, otherwise count the consonants of each element."
I've done some research to understand some factors of an ArrayList;
to start off, I did this:
import java.util.ArrayList;
public class izeOfArrayList {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
int totalElements = arrayList.size();
System.out.println("ArrayList contains...");
for(int index=0; index < totalElements; index++)
System.out.println(arrayList.get(index));
}
}
This code just gets the number of elements currently stored in my ArrayList, and prints out each element.
I have three questions:
How can I add String values using switch statement?
How can I retrieve the contents of my ArrayList?
How can I check the size of each element in my ArrayList?
"declare on arraylist with the size of 5. Use switch statement to add string values to your arraylist. Retrieve the contents of your arraylist. Check the size of each element. If the element length is less than 8 rerun the program, otherwise count the consonants of each element."
Let's decode line by line:
declare on arraylist with the size of 5.
ArrayList<String> myList = new ArrayList<>(5);
Our ArrayList needs to be defined as a list of Strings, so we put those in the angle brackets. The constructor takes a starting size, which is specified as 5.
Use switch statement to add string values to your arraylist.
Completely unintelligible. switch statements are used in flow of control; we can decide to add string values based on some condition, but we cannot generate input with switch statements, and no conditions are specified. This following code is (seemingly) valid for this instruction:
String values = "values";
switch (values) {
case "values":
default:
myList.add(values);
}
Retrieve the contents of your arraylist.
This you have already (mostly) written up:
int totalElements = myList.size();
for(int index = 0; index < totalElements; index++)
String tempElem = myList.get(index); //get access to the individual elem
//here we're going to do something with the current string (probably)
}
Check the size of each element.
I'm assuming that by the 'size of each element', your professor is looking for the length of each String.
int tempElemLength = tempElem.length();
String objects have a length method, it returns an int.
If the element length is less than 8 rerun the program, otherwise count the consonants of each element.
This, while at first glace seems reasonable, is again unintelligible. Here's a possible interpretation of this line:
if (tempElemLength < 8) {
main(null);
} else {
int tempElemNumConsonants = countConsonants(tempElem);
//consonants are counted and now what?
}
Here is a complete response to your assignment as it is currently defined:
import java.util.ArrayList;
public class SizeOfArrayList {
public static void main(String[] args) {
ArrayList<String> myList = new ArrayList<>(5);
String values = "values";
switch (values) {
case "values":
default:
myList.add(values);
}
int totalElements = myList.size();
for (int index = 0; index < totalElements; index++)
String tempElem = myList.get(index);
int tempElemLength = tempElem.length();
if (tempElemLength < 8) {
main(null);
} else {
int tempElemNumConsonants = countConsonants(tempElem);
//consonants are counted and now what?
//guess print them out?
System.out.println('Item ' + index + ': ' + tempElem + ' -> number of consonants: ' + tempElemNumConsonants);
}
}
}
}
This is a solution to your problem as it has been provided; I will bet money that this is not the solution to your homework problem.
In another school of thought, if the focus of the assignment is basic use and understanding of ArrayLists and I was your professor, the assignment that I would have intended to give my students would be as follows:
Declare and ArrayList with the size of 5. Prompt the user for values until they enter 'quit'; use a switch statement to add all String values into the ArrayList that aren't just a number from [0-9]. Loop over each element in the ArrayList; if the length of any String element is less than 8, alert the user then restart the program. If all of the lengths are valid, sum up the consonants of each element. Print out each word and the consonant count, along with a final tally of the number of words along with the total number of consonants.
While I do know that this does not help you with the initial question, I hope it might be able to help you understand what your professor is trying to ask of you.

Most efficient way to find unique entries in a large data set

Before anything, I am making it clear that this is an assignment and I do not expect full coded answers. All I seek is advice and maybe snippets of code that helps me.
So, I am reading in about 900,000 words all stored in a arrayList. I need to count unique words using a sorted array (or arraylist) in java.
So far, I am simply looping over the given arrayList and use
Collections.sort(words);
and Collections.binarySearch(words, wordToLook); to achieve it like the following:
OrderedSet set = new OrderedSet();
for(String a : words){
if(!set.contains(a)){
set.add(a);
}
}
and
public boolean contains(String word) {
Collections.sort(uniqueWords);
int result = Collections.binarySearch(uniqueWords, word);
if(result<0){
return false;
}else{
return true;
}
}
This code has a running time of about 60 seconds but I was wondering if there is any better way to do this because running a sort every time an element is added seems very inefficient (but of couse necessary if I were to use binary search).
Any sort of feedback would be greatly appreciated. Thanks.
So, you are required to use a sorted array. That is ok, since you are (not yet) programming in the real world.
I will suggest two alternatives:
The first uses binary search (which you are using in your current code).
I would create a class that contains two fields: the word (a String) and the count for that word (an int). You will build a sorted array of these classes.
Start with an empty array and add to it as you read each word. For each word, do a binary search for the word in the array you are building. The search will either find the entry containing the word (and you will increment the count), or you will determine that the word is not yet in the array.
When your binary search ends without finding the word, you will create a new object to hold the word+count and add it to the array in the location where your search ended (be careful to make sure that your logic really puts it in the right spot to keep your list sorted). Of course, your count is set to 1 for new words.
Another alternative:
Read all of your words into a list and sort it. After sorting, all duplicates will be next to each other in the list.
You will walk down this sorted list once and create a list of word+count as you go. If the next word you see is the same as the last word+count, increment the count. If it is a new word, add a new word+count to your result list with count=1.
I would not use a sorted array. I would create a Map<String, Integer> where the key is your word and the value is the count of the number of occurrences of the word. As you read each word, do something like this:
Integer count = map.get(word);
if (count == null) {
count = 0;
}
map.put(word, count + 1);
Then just iterate over the map's entry set and do whatever you need to do with the counts.
If you know, or can estimate, the number of unique words then you should use this number in the HashMap constructor (so you don't grow the map many times).
If you use a sorted array, your run time cannot be better than proportional to NlogN (where N is the number of words in your list). If you use a HashMap, you can achieve a runtime that grows linearly with N (you save yourself the factor of logN).
Another advantage of using a Map is the memory used is proportional to the number of unique words, rather than the total number of words (assuming that you build the map while reading the words, rather than reading all words into a collection and then adding them to the map).
public static int countUnique(array) {
if(array.length == 0) return 0;
int count = 1;
for i from 1 to array.length - 1 {
if(!array[i].equals(array[i - 1])) count++;
}
return count;
}
This is a O(N) algorithm in pseudocode for counting the number of unique entries in a sorted array. The idea behind it is that we count the number of transitions between groups of equal elements. Then, the number of unique entries is the number of transitions plus one (for the first entry).
Hopefully you see how to apply this algorithm to your array after the elements are sorted.
You could always use comparator to get unique values.
List newList = new ArrayList(new Comparator() {
#Override
public int compare(words o1, words o2) {
if(o1.equalsIgnoreCase(o2)){
return 0;
}
return 1;
}
});
Now count:
words - newList = no. of repeated values.
Hope this helps!!!!

2D Array but with indexing - java

I'm looping into a number of rows and trying to filter these rows with some if statements. within each if statement I need to have an index for a number of elements. I could have done that using 2d String[][] but the problem is I don't know what is the size of each row at this stage.
I'm looking to store my data like the following :
0 1 3 4 5 6 7 etc..
0 str str str str str str str
1 str str str
2
3 str str str str str str
Any suggestion would be appreciate it
Edit:
Sorry if my question wasn't clear. But I'll explain it more here.
My Loop looks like this:
newArrayList
for (i; i < List ;i++)
{
if(...)
{
newArrayList.add.(0, List.get(i));
} else if(...)
{
newArrayList.add.(2, List.get(i));
} else if(...)
{
newArrayList.add.(6, List.get(i));
}
}
The above code doesn't work but I'm just trying to explain what I need to do actually! My if statements can occur several times and I would like to consider an index for each if statement expectation plus a set of strings. Thanks.
You could try an ArrayList of ArrayList's:
ArrayList<ArrayList<String>> strings = new ArrayList<ArrayList<String>>();
strings.add(new ArrayList<String>()); // Adding a first array to the 'array of arrays'
strings.get(0).add("String1"); // Add a string to the first array,
// Similar to: arr[0][0] = "String1"
//To access them element by element use a double for, note that "s" is each element
for (ArrayList<String> l : strings) {
for (String s : l) {
}
}
PS: An ArrayList<Object> is like an array Object[] but more flexible. It has some useful methods like:
arr_list.get(index); // Getting an object in position 'index'
arr_list.add(object); // Adding an element (Similar to assignment in arrays)
Edit
If you know the number of "rows" then you have to add them to the array of arrays. With this for you are "creating the empty rows of your array":
Rows:
0
1
...
n
for (int i = 0; i < n; i++) { // n is the number of "rows"
strings.add(new ArrayList<String>());
}
Then add an element to a "row":
strings.get(0).add("String1"); // get(0) to obtain the first row, get(1) to obtain the second...
If your index is consecutive form 0 to n and you are inserting them in that order, but n is not known in advance: There are two classical solution:
1) If you do it with a pre-allocated fixed array, you obviously need two passes. The first pass is scanning the row and counting the elements. The second pass is then creating the index.
2) You can do it with a collection allowing dynamic growth via an .add(item) method, like List
If you will convert the collection to an fixed size array later, then it is maybe faster to use method 1) since the add method may be slower due to memory management / allocation / re-allocation.
If your index is consecutive form 0 to n and n is known in advance, but you are inserting the elements not in that order:
You should use solution 1) above.
If your index is not consecutive and n is known known in advance:
3) You create a Map<Integer,String> strings and add the elements via strings.put(index, string) (in any order).
If your index is not unique (as we have finally found out):
4) You crate a Map<Integer,ArrayList<String>> stringMap and add elements via
addStringForIndex(String string, Integer index)
{
listForString = stringMap.get(index);
if(listForString == null) {
listForString = new ArrayList<String>;
map.put(index, listForString);
}
listForString.add(string);
}
If you don't know the size of your array, you could use a List implementation, for example:
ArrayList<ArrayList<String>> 2D = new ArrayList<ArrayList<String>>();
And then use a for-each loop

Array of linked lists of arrays for hash table

So I am creating a Hash Table that uses an Array of Linked Lists of Arrays. Let me take a second to explain why this is.
So I have previously implemented Hash Tables by creating an Array, and each element of the array is a Linked List. This way I could quickly look up a LL of 450,000 elements by searching for the hash value first in the array, and searching the elements of this LL. I should add that this is a project for school and I cannot just use the Hash Tables that comes with java.
Now I want to do something similar... but I massive have a LL of Arrays that I need to search. Here each element of the LL is line of a text file, which represented by a 4 element array, where each of the 4 elements is a different string that was tab delimited in the input file. I need to be able to quickly access the 2nd, 3rd, and 4th string that was located in each line, and that is now an element of this array.
So What I want is to be able to create an Array of LL of Arrays... first I will find the sum of the ascii values of the second element of an array. Then I will hash the entire array using this value into by Hash Table. Then when I later need to find this element, I will go to the corresponding element of the array, where I have a list of arrays. I will the search for the 2nd value of each array in the list. If i find the one I want, then I return that array, and use the 3rd and 4th element of this array.
As I said, I have this working fine for an Array of LL, but adding the extra dimension of Arrays inside has thrown me off completely. I think it is mostly just figuring out syntax, since I have successfully initialized a Array of LL of Arrays (public static LinkedList[] RdHashLL) so it appears that Java is okay with this in principal. However, I have no idea how to put elements into the Hash Table, and how to read them out.
Below is my code for a ARRAY OF LINKED LISTS that works FINE. I just need help getting it to work for an ARRAY OF LL OF ARRAYS!
public class TableOfHash{
public static LinkedList<String>[] HashLL;
//HASH FUNCTION - Finds sum of ascii values for string
public static int charSum(String s){
int hashVal = 0;
int size = 1019; //Prime Number around size of 8 char of 'z', (8 chars is amoung largest consistantly in dictionary)
for(int i = 0; i < s.length(); i++){
hashVal += s.charAt(i);
}
return hashVal % size;
}
//CREATE EMPTY HASH TABLE - Creates an array of LL
public static void makeHash(){
HashLL = new LinkedList[1019];
for(int i=0; i<HashLL.length; i++){
HashLL[i] = new LinkedList<String>();
}
}
//HASH VALUES INTO TABLE!
public static void dictionary2Hash(LinkedList<String> Dict){
for(String s : Dict){
HashLL[charSum(s)].add(s);
//Finds sum of char vales of dictionary element i,
//and then word at i to the HashLL at point defined
//by the char sum.
}
//Print out part of Hash Table (for testing! for SCIENCE!)
//System.out.println("HASH TABLE::");
//printHashTab();
}
//SEARCH HashTable for input word, return true if found
public boolean isWord(String s){
if(HashLL[charSum(s)].contains(s)){
wordsfound++;
return true;
}
return false;
}
}
I have made some attempts to change this, but for things like if(HashLL[charSum(s)].contains(s)) which searches the LL at the element returned by charsum(s)... I have no idea how to get it to work when it is a LL of Arrays and not of Strings. I have tired HashLL[charSum(s)].[1].contains(s)), and HashLL[charSum(s)][1].contains(s)), and various other things.
The fact that a Google search for "Array of Linked Lists of Arrays" (with quotes) turns up empty has not helped.
Last bit. I realize there might be another data structure that would do what I want, but unless you believe that a Array of LL of Arrays is a totally hopeless cause, I'd like to get it to work as is.
if you have
LinkedList<String[]>[] hashLL;
you can read a specific String like this (one of many ways)
String str = hashLL[outerArrayIndex].get(listIndex)[innerArrayIndex];
To write into the fields, this is possible (assuming everything is initialized correctly).
String[] arr = hashLL[outerArrayIndex].get(listIndex);
arr[index] = "value";

Categories