How to add key & element to the existing hash table in Java? - java

Here is my code:
for (int j = 0; j < modulePass1AL.get(i).modSize; j++) {
System.out.printf("for module %d: put into entirememoryMapHashtable:%d,%d\n", i, arrayPerModule[j][0], arrayPerModule[j][1]);
entirememoryMapHashtable.put(arrayPerModule[j][0], arrayPerModule[j][1]);
}
I want to add arrayPerModule[j][0] and arrayPerModule[j][1] to a hash table called entirememoryMapHashtable, which is a big hash table that is supposed to keep the information from each arrayPerModule (I have 4 arrayPerModule arrays in total -- they all have different array length).
However, I think my code is instead, updating the contents of entirememoryMapHashtable, by keep adding arrayPerModule from the zeroth index of entirememoryMapHashtable.
Please help me fix this.
Thank you!

put(...) method from Map interface expects a key and a value. Remember, the key must be unique...
Check if in arrayPerModule[j][0] you dont have repeated elements, otherwise, you will update the values for that key. If you don't need to use arrayPerModule[j][0] as key, in this context, you could use the index.

Related

Optimization of deletion nodes in 2-d array

I have double dimensional array of dimensions 720x90. Let's denote rows by R and C as columns.
R1 = {C1,...,C90}
....
R720 = {C1,...C90}
Now, I want to see if any of the data in any of the rows appears anywhere else in any other rows. For instance, lets say the data in row 470 and column 67 is a duplicate of row 672 and column 34. In that case, I want to remove both row 470 and row 672 from the data set and continue checking. After I have checked all the rows, I want to print just the index of the rows that have survived. I have written a brute-force method of this. However, when I run this code, it never returns and I am not able to diagnose why. Also, is there a more efficient way to do this?
//check all the subsets of the interleaved data
public static int checkSubsets(String[][] subsets){
List subset = new ArrayList();
for(int i = 0; i< 720; i++){
for(int j = 0; j < 90; j++)
subset.add(subsets[i][j]);
}
Object duplicate;
Iterator itr = subset.iterator();
while(itr.hasNext()){
duplicate = itr.next();
while(itr.hasNext()){
subset.remove(duplicate);
itr=subset.iterator(); //to avoid concurrent modification
itr.next();
}
}
return subset.size();
}
Clarifications: Lets say I am iterating through looking at each value in the matrix. I take the first value in R1 C1 (row 1 - column 1). I find that these values are found somewhere in the 12, 346,123, 356 row. Then I remove all those rows from the matrix. So now the matrix is 5 rows smaller. I stop checking row 1 now and move onto row 2. I continue checking, skipping over row 12, 346, 123, and 356. Hence, I am after a row that is unique (has 90 values that are all unique).
I am not sure what the code you wrote has to do with the requirement, I will give you the approach of the answer yet you have to try it yourself first.
it is clear that you need to iterate on each row to check for possible duplicates yet this will cause a performance failure , you can overcome this with a smiple use of HashMap, first store each entry in the map , the key will be the value of the node of the array, and the value should be the coordinates of this node.
When iterating over the array for each row you should find the y coordinates from the map which is common between all nodes of the row, so duplicate rows detected.
In order to avoid keep checking the already removed rows try to store all the rows to be deleted and remove them once you are done, you can use Set to store them to avoid duplicate.
Good luck with the implemenation.
The algorithm is almost there, but helpfull data-structures are missing.
To add a bit of spice I used Java 8 somewhat.
As you did one can collect the values to check for duplicates.
However one needs to remember the first row of that value, as only there it is still unknown whether a duplicate exists.
public static int checkSubsets(String[][] subsets) {
// The results.
final Set<Integer> duplicateRows = new HashSet<>();
// From the first occurrence of a duplicate value we do not know it yet,
// so need to remember.
final Map<String, Integer> firstRowOfValue = new HashMap<>();
for (int i = 0; i < subsets.length; ++i) {
for (int j = 0; j < subsets[i].length; ++j) {
final String value = subsets[i][j];
Integer oldRow = firstRowOfValue.putIfAbsent(value, i);
if (oldRow != null) { // Duplicates
duplicateRows.add(i);
duplicateRows.add(oldRow);
// oldRow might already be added if third duplicate or same row.
}
}
}
IntStream.rangeOf(0, subsets.length)
.filter(i -> !duplicateRows.contains(i))
.forEach(System.out::println);
return subsets.length - duplicateRows.size();
}
The IntStream part would be in java 7:
for (int i = 0; i < subsets.length; ++i) {
if (!duplicateRows.contains(i)) {
System.out.println(i);
}
}
With java 7 you can safely substitute here putIfAbsent with put.

2 dimensional array & method calls - beginner

I'm currently working on a homework assignment for a beginner-level class and I need help building a program that tests if a sodoku solution presented as an int[][] is valid. I do this by creating helper methods that check both rows, columns and grids.
To check the column I call a method called getColumn that returns a column[]. When I test it out it works fine. I then pass it out on a method called uniqueEntries that makes sure that there are no duplicates.
Problem is, when I call my getColumn method, it returns an array consisting of only one number (for example 11111111, 22222222, 33333333). I have no idea why it does that. Here is my code:
int[][] sodokuColumns = new int[length][length];
for(int k = 0 ; k < sodokuPuzzle.length ; k++) {
sodokuColumns[k] = getColumn(sodokuPuzzle, k);
}
for (int l = 0; l < sodokuPuzzle.length; l++) {
if(uniqueEntries(sodokuColumns[l]) == false) {
columnStatus = false;
}
}
my helper is as follows
public static int[] getColumn(int[][] intArray, int index) {
int[] column = new int[intArray.length];
for(int i = 0 ; i < intArray.length ; i++) {
column[i] = intArray[i][index];
}
return column;
}
Thanks !
You said:
when I call my getColumn method, it returns an array consisting of only one number (for example 11111111, 22222222, 33333333).
I don't see any issue with your getColumn method other than the fact it's not even needed because getColumn(sodokuPuzzle, k) is the same as sodokuPuzzle[k]. If you're going to conceptualize your 2D array in such a way that your first index is the column then for your purpose of checking uniqueness you only need to write a method to get rows.
The issue you're having would seem to be with another part of your code that you did not share. I suspect there's a bug in the logic that accepts user input and that it's populating the puzzle incorrectly.
Lastly a tip for checking uniqueness (if you're allowed to use it) would be to create a Set of some kind (e.g. HashSet) and add all of your items (in your case integers) to that set. If the set has the same size as your original array of items then the items are all unique, if the size differs there are duplicates.

B-Tree Implementation

I was reading about implementing B-Tree from Rober Sedgewik's and found this snippet in the else part of search method from this link: http://algs4.cs.princeton.edu/62btrees/BTree.java.html
// internal node
else {
for (int j = 0; j < x.m; j++) {
if (j+1 == x.m || less(key, children[j+1].key))
return search(children[j].next, key, ht-1);
}
}
I banged my head but couldn't understand why he directly starts comparing key with j+1th element of children and not jth.
Could someone please through some light upon this specific point?
If you look at his declaration of the less() method, you'll notice that it uses compareTo.
Essentially, what he wanted to do was key.compareTo(children[j+1].key)
But why would he use j+1 instead of j? To understand this, look at the first part of his conditional statement; he uses j+1 == x.m, meaning that he wants to test to see if j+1 is the limit. If j+1 = x.m, he doesn't want to continue incrementing j, so he returns. However, if it is not the limit yet, check compare the current key with the next key in the list (because the next key exists). IF the next key in the list is "less" than the current key, search for the current key.
In short:
If j+1 doesn't exist, the first half of the if statement will catch it and it will break out of the for loop. Otherwise, check j+1's key.

Mocking contains() with a String[][]

I have two SQL tables. After grabbing both tables in ResultSets, I've stored them in String[][]s, ordered by a common id column. These tables should contain the same data, however one may have duplicates of the same row from the other. In order to check if every String[] in table A is present at least once in table B, I need to construct a somewhat efficient contains()-esque method for String[].
This is what I have so far, but am stumped (also not sure if there's a much more efficient solution). Give it the source table and target table. It takes each String[] in the source table and (should) go through each String[] in the target table and find an instance of the source String[] somewhere in the target String[][] by checking if there's at least one String[] that matches the original String[], element by element. Can anyone point me in the right direction and/or fill in the blanks? This isn't homework or any assignment, I'm refactoring some code and am having a major brain fart. Thanks!
public boolean targetContainsSource(String[][] s, String[][] t) {
boolean result = true;
//For each String[] in String[][] s
for (int i = 0; i < s.length; i++) {
//For each String[] in String[][] t
for (int j = 0; j < t.length; j++) {
//For each String in t's String[]
for (int k = 0; k < t[0].length; k++) {
if (!s[i][k].equals(t[j][k])) {
}
}
}
}
return result;
}
Your innermost loop could be removed by using Arrays.equals().
For each element of the first array, you should define a found boolean variable, that would only be set to true once the element is found in the second array. Once the second loop is finished, if this variable is still false, you have found an element of the first array that is not in the second, and you can return immediately.
And of course, as soon as this variable is set to true, you can break out of the second loop.
Essentially, you generally need to do the following:
use a strong hash function to take a hash of each row: this gives you a single integer (probably a long to be strong enough) or single string/byte array representing the entire row
then proceed as though you were comparing two "lists" of rows. At least one of these "lists" should actually be stored in a HashSet/HashMap, whose contains() method is efficient.
For the hash function you could use MD5 (e.g. you can use this code, but use "MD5" instead of "SHA-1"). You can use MessageDigest.compare() to compare to byte arrays representing hash codes.
If you only have a small number (say, a few tens of thousands) of rows, then you could use a 64-bit hash code-- this just has the advantage that each hash is stored in a long so they're a bit easier to shufty about and compare. But 64-bit hash codes are only strong enough for guaranteeing uniqueness of hashes of tens to hundreds of thousands of objects (=different rows in your case).
P.S. If you're prepared to store all of the data in memory, then you could also just use as the "hash" of each row all of the columns concetenated together into a single string. The trick is to make the check efficient to have one of the tables' row representations stored in a HashSet/HashMap.

Iterable/Multidimensional array next method issues

Disclaimer: This is for a homework assignment.
I am currently working on an assignment where I need to implement an iterable interface in order to pass each array from a square two-dimensional array. This array is supposed to represent a grid of numbers (so I will be referring to them as such [row][col]). My problem is that I want to use the same next method to iterate through the rows and the columns. First, is this possible? Second, any suggestions/hints?
My next method currently looks like this:
public Data[] next(){
Data [] holder = new Data[ray.length];
for (int i = 0; i <ray.length; i++)
holder[i]=ray[counter][i];
counter++;
return holder;}
EDIT: I am aware of being able to switch counter and i in ray[counter][i], but I'm not sure how to have it do both if that's possible.
ray is the multidimensional array and count is an attribute of the Iterator method I've created (It's initialized to 0 and this is the only method that changes it). I know I cannot return the "column" of ray this way, so how would I go about having next call columns and rows?? Thanks for any of the help. I'll be standing by if you have further questions.
My problem is that I want to use the same next method to iterate through the rows and the columns. First, is this possible?
Yes it is possible, assuming you mean what I think you mean. (The phrase "iterate through the rows and the columns" is horribly ambiguous.)
Since this is a homework exercise here are a couple of hints:
You need two counters not one.
When you get to the end of one row you need to go to the start of the next row. (Obviously!) Think about what that means if you've got two counters.
This should be enough to get you on the right track.
I want a row by row iteration and a column by column iteration.
This is also a horribly ambiguous description, but I'm going to interpret it as meaning that sometimes you want to iterate left to right and top to bottom, and other times you want to iterate top to bottom and left to right.
That is also possible:
One possibility is to use an extra state variable to tell the iterator which direction you are iterating; i.e. row within column, or column within row.
Another possibility is to implement two distinct Iterator classes for the two directions.
The problem is that the iterator class is only supposed to have one counter and returns an single-dimension array.
You've (finally) told us unambiguously that the iterator is supposed to return an array. (A good dentist could pull out a tooth quicker than that!)
So here's a hint:
Returning the ith row is easy, but returning the jth column requires you to create a new array to hold the values in that column.
My advice is: transform the 2d array to a list and iterate.
When initialize the Iterator, transform the list. Then you could iterate the list easily.
Following is p-code, you could enrich the implementation in your homework. Hope it helps you!
class TwoDimeIterator implements Iterator<Date> {
List transformedList = new ArrayList();
int cursor = 0;
/** transform to a list row by row.
So you could define your Iterator order.**/
TwoDimeIterator(){
for(int i=0; i < ray.length; i++)
for(int j=0; j < ray[0].length; j++)
transformedList.add(ray[i][j]);
}
public Date next() {
return transformedList.get(cursor++);
}
public boolean hasNext() {
return cursor != transformedList.size();
}
//...
}

Categories