Iterable/Multidimensional array next method issues - java

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();
}
//...
}

Related

Find adjacent element in 2D array

I've been trying to get over a problem :
Let's say, you have an 3*4 (3 row 4 col) :
Let's take A[1][3] for example :
He's adjacent to the A[2][3], who is adjacent to A[2][2]
My goal, like the "SameGame" Game, is to find a way in order to have every adjacent similar characters' positions in an array in order to highlight them.
At first, I was thinking about doing a loop to check neighbors everytime I found some adjacent similar character, but it seems like a lot of pain for something like this.
if((this.tabi[x][y] == this.tabi[x+1][y])) {
this.group[x+1][y] = this.tabi[x+1][y];
this.group_size++;
// call it again for this.tabi[x+1][y]
}
}
Is there a more "performant-wise" solution ?
The board is generated randomly :
for (i=0; i<row; i++) {
for (j=0; j<col; j++) {
tab[i][j] = A OR B OR C
}
}
Thanks !
You could use a pathfinding algorithm like Dijkstra or Fjord-Warshall between two Group-Elements and treat every other group as an obstacle.
It's hard to tell, if you don't post a bit more about how you manage your playing field, elements and groups.

Implementing a SelectionSort capable of handling array list, linked list, and doubly linked list in java

BACKGROUND: I want to implement a selection sort capable of handling an array list, a linked list, and a doubly linked list. For each list type I have a position{} and list{} class. The position{} class is what holds the list, (i.e. class position{int head; list tail;}). While the LIST{} contains the next(), previous(), end(), Insert(), first() methods and uses position{}, it does not contain the list class itself, the list class itself that constructs the list is called class position{}.
QUESTION: My problem is not with making the selection sort compatible, I have achieved this by only using the commands that are common between he three list abstract data types. My problem is that my selection sort returns the same list and does no sort of sorting. The list printed after the sort is the same as the list printed before the sort. Any help is appreciated.
output
before selection sort
2 879 621 229 702 40 243 312 247 46 711 241
after selection sort
2 879 621 229 702 40 243 312 247 46 711 241
My list ADT's are correct, the problem lies in my poor selectionsort.
public static void SelectionSort(LIST A) {
POSITION i, j, maxp, temp;
for(i = A.Previous(A.End()); !i.isEqual(A.First()); i = A.Previous(i)) {
maxp = i;
for(j = A.First(); !j.isEqual(i); j = A.Next(j)) {
if((Integer)A.Select(j) > (Integer)A.Select(maxp)) {
maxp = j;
}
}
temp = i;
A.Insert(i, A.Select(maxp));
A.Insert(maxp, A.Select(temp));
A.Delete(maxp);
A.Delete(i);
}
}
You're first inserting something at index i, then inserting something at index maxp, then deleting the thing at index maxp and then deleting something at index i. Assuming Insert() and Delete() do what their names imply, this sequence of operations leaves your list in the initial state after each iteration of the loop since the deletions undo the insertions.
As a side note, this code doesn't follow Java's naming conventions which makes it harder to read than it needs to be.
How do the Insert, Select, and Delete methods function? Is it possible that Delete is removing the element you just Inserted?
Have you verified that the isEqual (and methods mentioned above) operator is behaving as expected?
From your algorithm, this is what I infer is happening:
you loop over all the elements, starting at the second last, moving towards the front.
Locate the maximal element in the subset from 0 to i
Insert the maximal element found (at index maxp) into the array at index i
Insert the element originally at index i back into the array at the posistion originally taken by maxp
Remove the i and maxp
First off, why do you need to remove the elements? Does Insert duplicate the element? If you call Delete on a list with two instances of the element you are trying to delete, which one will it delete? The first? Is this what you want?
Perhaps you need a new method, Replace which replaces the element at the given index instead. Then you wouldn't need to remove it after. Even better would be a Swap method which swaps 2 elements in a List.
An easier to follow solution might even create a new list to store the elements instead of performing the sort in place. While this takes more room, it would be easier to implement in the short term, and once it is working, you can optimize it with an in place sort later.
You should only need to do one insert and one delete. You are supposed to search the unsorted part of the list for the smallest (or biggest) element, then move it to the end of the sorted part of the list. That's one insert and one delete.
Also be careful that you are deleting the correct element. If you insert before you delete, then the correct index to delete may be shifted by one if the insert went before that position.
This is the correct answer, it took me a clear mind, probably caused by a good cup of tea, to finally sort things out in the end... My insert and delete methods were just not right, one little change and wallah. cheers. Thanks for all the replies.
public static void SelectionSort(LIST A) {
POSITION i, j, maxp, temp;
for(i = A.Previous(A.End()); !i.isEqual(A.First()); i = A.Previous(i)) {
maxp = i;
for(j = A.First(); !j.isEqual(i); j = A.Next(j)) {
if((Integer)A.Select(j) > (Integer)A.Select(maxp)) {
maxp = j;
}
}
temp = i;
A.Insert(A.End(), A.Select(maxp));
A.Delete(A.Previous(A.End()));
A.Insert(maxp, A.Select(temp));
A.Delete(temp);
}
}

check if array is full

I am trying to do check if an array is full and print out to the user he is unable to enter more books.
static Object[][] books=new Object[2][];
I am asking 3 values from the user and am storing to another array called "row".
Object[]row=new Object[3];
After that i loop through the books array and check if it has a null value inside of it and add the "row" array with the given values of the user.
the problem am having is i cant give any feedback if books array is full after entering two rows of values.
boolean empty=false;
while(empty==false){
for (int i = 0; i < books.length; i++) {
if(books[i]==null){
books[i]=row;
empty=true;
break;
}
}
}
Why not having a variable
int bookCounter = 0;
which you can increase/decrease everytime you add/delete books and then just check it against your max number of books (which I assume is books.length)
In this way you don't need to loop over the array, which is not efficient.
There is no need for the while loop. After the for loop ends, check your empty variable that you're already setting. If it's false, then give your feedback to the user.
Arrays are always full. Even each element is null. If you initialize it with the size of 10, then JVM will alocate memory and fill the all the arrays positions with default value. What is: 0 for primitives numbers and char type, false for primitive boolean type and null for Objects.
So, your code won't work with a int[] for instance. Because there won't exist any null element.
That's why you dont have a count() method... You can create a method that is named countNotNull(). But you'll need to interate for all the array long.
The best solution is to use a variable to count when you add/remove itens form array. As
Guillermo Merino said.

Java ArrayList clear() function

Let's say I have a ArrayList<String> data;
I'm adding some data into this Array, using data.add() function.
Let's say I've added 10 Strings into this array. The size of the array is 10 now.
How do i destroy all elements in the array? The data.clear() function just set's all 10 elements to null. So when I try to add another element, it just get's on the 11 position. I want just to start it over from 0;
I can use a for loop to replace all the data, but I really think there is a way just to empty the ArrayList. Is it?
Your assumptions don't seem to be right. After a clear(), the newly added data start from index 0.
If you in any doubt, have a look at JDK source code
ArrayList.clear() source code:
public void clear() {
modCount++;
// Let gc do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
You will see that size is set to 0 so you start from 0 position.
Please note that when adding elements to ArrayList, the backend array is extended (i.e. array data is copied to bigger array if needed) in order to be able to add new items. When performing ArrayList.clear() you only remove references to array elements and sets size to 0, however, capacity stays as it was.
ArrayList.clear(From Java Doc):
Removes all of the elements from this list. The list will be empty after this call returns
After data.clear() it will definitely start again from the zero index.
data.removeAll(data); will do the work, I think.
it's not true the clear() function clear the Arraylist and start from index 0
Source code of clear shows the reason why the newly added data gets the first position.
public void clear() {
modCount++;
// Let gc do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
clear() is faster than removeAll() by the way, first one is O(n) while the latter is O(n_2)

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.

Categories