I'm trying to write code that will create multiple HashSets using a for loop. I'm trying to store occurrences of unique words based on their length. For example, a word of length 4 would go in HashSet A, while a word of length 20 would go in HashSet B. Instead of creating 16 HashSets manually, is there a way for me to use a for loop (int i=4; i<21; i++)? Thank you!
Rather than having 16 different HashSet's, you can have a Map<Integer, Set<String>>.
So, while adding, you can just test whether a key is already there or not. If a key is there, just add the word to the Set for that key, else add a new entry.
So, here're the steps you need to follow: -
Get the length of the word. Say length.
Test if Map contains key length - Map#containsKey(Object)
If length key is there, get the Set for that key - Map#get(Object). And add the word to that Set.
If length key is not there, create a new HashSet, add the current word in it. And add a new entry in your Map with the current length as key - Map#put(K, V)
HashSet<String>[] sets= HashSet<String>[21];
for(int i=4; i<21; i++)
sets[i]= new HashSet<String>();
Later when you want to add words:
for(String word: words){
sets[word.length()].add(word);
}
P.s. I do not use the array indexes 0..3 but the code looks nicer this way and it is really only very little wast of memory.
You can make them in a loop and put them into a list or an array...
List<HashSet<String>> sets = new ArrayList<HashSet<String>>()
for (int x=0;x<16;x++) {
sets.add(new HashSet<String>());
}
Related
I am a beginner programmer working on a Two Sum problem. An array of integers are given as well as an integer, target. The intention of the program is to find which two numbers in the array of integers add up to the target integer. The most efficient solution I am seeing is quite ingenious in how it iterates over all of the integers in the array and checks if the difference between each integer in the array and the target number is another integer in the array. Then those two would be the solution. My issue is with the HashMap part. How would an empty HashMap .containsKey() work if it is empty and has no keys in it?
class Solution {
public int[] twoSum(int[] nums, int target) {
int n=nums.length;
Map<Integer,Integer> map=new HashMap<>();
int[] result=new int[2];
for(int i=0;i<n;i++){
if(map.containsKey(target-nums[i])){
result[1]=i;
result[0]=map.get(target-nums[i]);
return result;
}
map.put(nums[i],i);
}
return result;
}
}
I tried to research solution explanations but all of them just said that the solution checks if the values are in the map but how would any values be in the map if it is empty and was never linked to the integers array? Thanks a lot for the help.
I give you a phone book. I ask you if 'Ryan Siegrist' is in it. You open it up intending to scan it (or perhaps you're going to be smarter about it and use a fancy algorithm, such as binary searching by opening it to the middle page to see if you should go 'higher' or 'lower') - and it turns out the phone book is simply empty.
The correct answer is of course 'no, Ryan Siegrist is not in this empty phone book'.
HashMap is no different. .containsKey(whateverYouLike) returns false if you invoke it on an empty list. Why wouldn't it?
The stated algorithm does nothing the first time you loop, but note that at the end of the for look, whether the if ( containsKey ) check worked out or failed, an entry is added to the map. So the second and further runs through that loop, the map is no longer empty.
Short version:
If the map is empty and it does not contain a key. Then the line:
map.put(nums[i],i);
will still execute. This is because it is outside of the if check.
Long version
So when the code first iterates through the array, the HashMap is always empty at first because it was initialized as such:
Map<Integer,Integer> map=new HashMap<>();
Then the first iteration of the if check returns false:
if(map.containsKey(target-nums[i]))
But it still executes the line of code which will associate the map with the value of nums at the index of i with the index of i as the value for the map.
Then the loop will continue iterating until a solution is found or the loop terminates.
I have a lot of words at hand. What I need to do is to save them and count every different word. The original data may contain some duplicate words.Firstly, I want to use Set, then I can guarantee that I only get the different wrods. But how can I count their times? Is there someone having any "clever" idea?
You can use MultiSet from the Guava library.
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multiset.html
You can use Map to solve this problem.
String sample = " I have a problem here. I have a lot of words at hand. What I need to do is to save them and count every different word. The original data may contains duplicate words.Firstly, I want to use Set, then I can guarantee that I only get the different wrods. But how can I count their times? Is there someone having any clever idea?";
String[] array = sample.split("[\\s\\.,\\?]");
Map<String,Integer> statistic = new HashMap<String,Integer>();
for (String elem:array){
String trimElem = elem.trim();
Integer count = 0;
if(!"".equals(trimElem)){
if(statistic.containsKey(trimElem)){
count = statistic.get(trimElem);
}
count++;
statistic.put(trimElem,count);
}
}
maybe you can use hash, in java, it's HashMap(or HashSet?)
you can hash every word, and if that word has been hashed, increment some value associated with it by one, that is the idea.
What I'm trying to do is set up 14 arrays that will be of both type string and double to be able to accept input into the first index, and then the next time that the user enters in their information I don't want to add that information into an index that's already been given a value, but I do want to add that new information into the next index of that array. Do I just ++Array[index]? I'm also trying to set up this program to allow the user to be able to access 1 of 3 different IFstatements at a time to input values. If they enter input into an Array in IFstatement1, and then leave IFstatement1, go to IFstatement2 to input something, and then want to come back to IFstatement1 and input data into Arrays there, will the program know to add the newest user inputs into the next index in the array by using the ++Array[index] indicator, or do I have to do something else? How do I accomplish this?
Try looking into the ArrayList object this should work for what you are looking for and it has a nice .add() function to add to the end of the list.
List<String> l1 = new ArrayList<String>();
l1.add("String");
l1.add("Another");
for (String str : l1) {
System.out.println(str);
}
This will add the strings and provide you the iterator.
If you want another with Doubles just change for or you can have one without generics that will just hold objects <> remove them. Then your for loop would traverse the objects instead.
You can't use ++Array[index] to add an element to an array in Java. As in other statically typed languages, array's are given a size when they are created and can't contain more values then their initial size. So for instance int numbers[10]; can hold 10 integer values. If you want to set the values in that array use something like this:
int numbers[10];
for (int i = 0; i < 10; i++) {
numbers[i] = 1 + 1;
}
With regards to the user input you describe, you would need to use some form of looping, maybe a while loop?
I need to sort an array based on the positions held in another array.
What I have works, but it is kinda slow, is there a faster/better way to implement this?
2 Parts:
Part1
int i = mArrayName.size();
int temp = 0;
for(int j=0;j<i;j++){
temp = mArrayPosition.get(j);
mArrayName.set(temp, mArrayNameOriginal.get(j));
}
In this part, mArrayPosition is the position I would like the mArrayName to be in.
Ex.
input:
mArrayName= (one, two, three)
mArrayPosition = (2,0,1)
output:
mArrayName= (three, one two)
Part 2
int k=0;
int j=0;
do{
if(mArrayName.get(k)!=mArrayNameOriginal.get(j)){
j++;
}else{
mArrayIdNewOrder.set(k, mArrayId.get(j));
k++;
j=0;
}
}while(k < mArrayName.size());
}
In this part, mArrayName is the reordered name array, mArrayNameOriginal is the original name array.
Ex.
mArrayName = (three, one, two)
mArrayNameOriginal = (one, two, three)
Now I want to compare these two arrays, find which entries are equal and relate that to a new array that has their rowId number in it.
Ex.
input:
mArrayId = (001,002,003)
output:
mArrayIdNewOrder = (003,001,002)
So then I will have mArrayIdNewOrder id's matching up with the correct names in mArrayName.
Like I said these methods work, but is there a faster/better way to do it? I tried looking at Arrays.sort and comparators but they only seem to sort alphabetically or numerically. I saw something like I can create my own rules inside the comparator but it would probably end up being similar to what I already have.
Sorry for the confusing question. I'll try to clear up any ambiguities if needed.
The best performance read I've found is Android's Designing For Performance doc. You are violating a couple of the "Android way" style of doing things that will help you.
You are using multiple internal getters inside each loop for what looks like a simple value. Redo this by accessing the fields directly.
For extra credit, post your performance comparison results! I'd love to see em!
You could use some form of tuple, some class to hold both id and name. You'll just to have a java.util.Comparator that compares it accordingly, both elements will move together and your code will be cleaner.
This data structure might be convenient for the rest of your program... if not, just take things off it again and you're done.
If your order indexes are compact, i.e. from index 0 to size - 1, then just use an array and create the updated list afterwards? About something like
MyArray[] array = new MyArray[size];
for(int j=0;j< size;j++) {
array[ mArrayPosition.get(j) ] = mArrayName.get(j);
}
// create ArrayList from array
Im given a task which i am a little confused to understand. Here is the question statement:
The following program should read a file and store all its tokens in a member variable.
Your task is to write a single method that returns the number of items in tokenMap, the average length (as double value) of the elements in tokenMap, and the number of tokens starting with character "a".
Here the tokenMap is an object of type HashMap<String, Integer>;
I do have some idea about HashMap but what i want to know the "key value" for HashMap required is a single character or the whole word?? that i should store in tokenMap.
Also how can i compute the average length?
Looks like you have to use the entire word as the key.
The average length of tokens can be computed by summing the lengths of each token and dividing by the number of tokens.
In Java, you can find the number of tokens in the HashMap by tokenMap.size().
You can write loops that visit each member of the map like this:
for(String t: tokenMap.values()){
//t is a token
}
and if you look up String in the Java API docs you will see that it is easy to find the length of a String.
To compute the average length of the items in a hash map, you'll have to iterate over them all and count the length and calculate the average.
As for your other question about what to use for a key, how are we supposed to know? A hashmap can use practically any* value for a key.
*The value must be hashable, which is defined differently for different languages.
Reading the question closely, it seems that you have to read a file, extract each word and use it as the key value, and store the length of each key as the integer:
an example line
leads to a HashMap like this
an : 2
example : 7
line : 4
After you've built your map (made of keys mapping to entries, or seemingly elements in the question), you'll need to run some statistics over it to find
the number of keys (look at HashMap)
the average length of all keys (again, simple enough)
the number beginning with "a" (just look at the String)
Then make a value object containing these values and return it from the method that does the statistics.
I know I've given more information that you require, but someone else may benefit from a little extra help.
Guys there is some confusion. Im not asking for a solution. Im just confused for one thing.
For the time being, im gonna use String type as the key type.
The only confusion i have is once i read the file line by line, should i split it based upon words or based upon each character. So that the key value should be a single character type string or a String of whole word.
If you can go through the question statement, what do you suggest. That's all im asking.
should i split it based upon words or
based upon each character
The requirement is to make tokens, so you should split them based on words. Each word becomes a unique String key. It would make sense for the value to be the count of each token.
If the file you are reading has these three lines:
int alpha;
int beta;
float delta;
Then you should have something like
<"int", 2>
<";", 3>
<"alpha", 1>
<"beta", 1>
<"float", 1>
<"delta", 1>
(The semicolon may or may not be considered a token.)
Your average length would be ( 3x2 + 3x1 + 5 + 4 + 5 + 5) / 6.
Your length of tokens starting with "a" would be 5.0.
Look elsewhere on this forum for keySet and you should be good to go.