Adjusting 2 dimensional array's? - java

I made a 2 dimensional array like this:
char Grid[][] = {
{'#','#','#'}
{'#','#','#'}
{'#','#','#'}
}
and displayed it with this:
for (int row = 0; row < Grid.length; row++) {
for (int column = 0; column < Grid[row].length; column++) {
System.out.print(Grid[row][column]);
}
System.out.println();
}
I want to be able to simple adjust the elements in the array, like adding and removing elements. Since basic java (for some reason) doesn't seem to have any predefined functions to do this, i tried using the ArrayUtils class from common langs. I found a couple methods in the docs including "Add", "insert", and "remove" and tried something like this:
ArrayUtils.insert(Scene, Grid, 2); //(With "Scene" being the class name)
But as expected, it didn't work.
On another website, i read something about cloning the array, but i don't think this is the solution to my problem since i want to be able to move around an ASCII character, and i don't want to create a new array each time i move it.
EDIT: To be clear, i want to be able to either CHANGE the index value's or quickly remove then and place another on the exact spot.

arrays are basic types and are not used to add elements, for these operations ArrayList and depending if there is many inserts and deletes at any places LinkedList may be more convenient. ArrayUtils.insert should return a new array instance doing a copy of initial array.

Once created an array in java is with fixed length so in your case after you have used the Array Inicializer you end up with an array with length 3, having elements of type char array where each of them is with fixed length of 3 as well. To replace a given value all you need is to assign the new value to the proper indexes like :
Grid[i][j] = 'new character value';
As I've already said since the size is fixed you can not add new values to it, unless u copy the entire array in a new array of size (length +1) and place the new value on the desired position. Simple code demonstrating that:
private static void add(char[][] grid, int row, int column, char value) {
if (row < 0 || row > grid.length) {
throw new ArrayIndexOutOfBoundsException("No such row with index " + row + " inside the matrix."); // you are trying to insert an element out of the array's bounds.
}
if (column < 0 || column > grid[row].length) {
/*
* An array in Java is with fixed length so you should keep the index inside the size!
*/
throw new ArrayIndexOutOfBoundsException("Index " + column + " does not exists in the extended array!"); // you are trying to insert an element out of the array's bounds.
}
boolean flag = false; //indicates that the new element has been inserted.
char[] temp = new char[grid[row].length + 1];
for (int i = 0; i < temp.length; i++) {
if (i == column) {
temp[i] = value;
flag = true;
} else {
temp[i] = grid[row][i - (flag ? 1 : 0)];
}
}
grid[row] = temp; //assign the new value of the whole row to it's placeholder.
}
To remove an element from the array you would have to make a new array with size[length - 1], skip the element you would like to remove and add all the others. Assign the new one to the index in the matrix then. Simple code:
private static void remove(char[][] grid, int row, int column) {
if (row < 0 || row > grid.length) {
throw new ArrayIndexOutOfBoundsException("No such row with index " + row + " inside the matrix."); // you are trying to insert an element out of the array's bounds.
}
if (column < 0 || column > grid[row].length) {
throw new ArrayIndexOutOfBoundsException("No such column with index " + column + " at row " + row + " inside the matrix."); // you are trying to insert an element out of the array's bounds.
}
boolean flag = false; //indicates that the element has been removed.
char[] temp = new char[grid[row].length - 1];
for (int i = 0; i < temp.length; i++) {
if (i == column) {
flag = true;
}
temp[i] = grid[row][i + (flag ? 1 : 0)];
}
grid[row] = temp; //assign the new value of the whole row to it's placeholder.
}
If I define a method called print(char[][] grid) and put the code you use for printing then i'm able to do these tests:
add(Grid, 2, 3, '$'); //Add an element.
print(Grid);
System.out.println();
remove(Grid, 2, 0); // Remove an element.
print(Grid);
System.out.println();
Grid[0][0] = '%'; // Change an element's value.
print(Grid);
And the output is as follows:
###
###
###$
###
###
##$
%##
###
##$

Related

Populating a 2D Array with unique (non-random) values

Is there a way to populate a 2D Array with unique, nonrandom values? The compiler won't allow something like:
int[][] myArray=new int[5][5];
myArray[0]=new int[] {2, 1, 1, 1, 1};
to happen, and all of the tutorials I've seen on this have related to adding random numbers or populating the array from the start(not applicable to me, as my program depends on user input to know what number values to add). If this isn't possible, is there another method I should be using?
You should use a nested for loop:
for(i=0;i<arr.lenght;i++)
for(j=0;j<arr.lenght;j++)
After doing your nested loop, add something like this:
myArray[i][j]= userInput.next(); //assuming you are using Scanner class
what the nested loop does is iterate through each of the "spaces" the array has and because you are asking the user to input something each time, your array will populate in each "space" with the desired input.
Hope this helps.(ignore my edits, totally misread)
You can fill your 2D Integer (int) Array with either unique values throughout the entire Array or unique values only for each Row of the Array. There are several ways to do this sort of thing but we'll just stick with basic methods. The code is well commented:
User fills 2D Integer Array with Unique Rows only:
// Setup for Keyboard input to Console.
Scanner input = new Scanner(System.in);
// System Line Separator used in console display.
String ls = System.lineSeparator();
// Declare and initialize a 2D Object Array.
// We need to use Object so that all initialized
// elements will be null rather than 0 since 0
// could be supplied and will need to be checked
// for Unique. Since a 2D int array by default
// initializes all elements to 0, a supplied 0
// will never be considered Unique.
Object[][] myArray = new Object[5][5];
// Have User fill our 2D Array...
for (int row = 0; row < myArray.length; row++) {
// Display the Row User will be on to fill.
System.out.println(ls + "Enter values for Row #" + (row+1) +
" of " + myArray.length);
// Allow User to fill each column of the current Row...
for (int column = 0; column < myArray[row].length; column++) {
// Flag to indicate Uniqueness.
boolean unique = false;
// Integer variable to hold what the User enters in console
int value = 0;
// Continue looping to ensure the User supplied a proper
// integer value which is unique to the current 2D Array
// Row only.
while (!unique) {
// Display the Column User will be on to fill.
System.out.print("Column #" + (column+1) + " value: --> ");
// Trap User entries that are not Integer values. If any alpha
// characters are supplied with the value then an exception is
// automatically thrown which we trap.
try {
// Get input from User...
value = input.nextInt();
} catch (Exception ex) {
// Inform the User of an improper entry if an exception was thrown.
System.err.println("You must supply an Integer value. Try again...");
input.nextLine(); // Clear Scanner buffer
// Allow User to try another entry for the same Column
continue;
}
// See if the supplied value is already contained within the
// current array Row...
for (int j = 0; j < myArray[row].length; j++) {
// Stop checking if we hit null. Nothing there yet.
if (myArray[row][j] == null) {
unique = true;
break;
}
// If a row's column element equals supplied value...
else if ((int)myArray[row][j] == value) {
// Value is not Unique
unique = false;
System.err.println("Value is not unique to Row #" +
(row+1) + " - Try Again...");
break; // Break out of checking early
}
// The supplied value is unique.
else {
unique = true;
}
}
}
//Place the value into the current
// Column for the current Row
myArray[row][column] = value;
}
}
// Convert the 2D Object Array to a 2D int Array
int[][] intArray = new int[myArray.length][myArray[0].length];
for (int i = 0;i < myArray.length; i++) {
for (int j = 0; j < myArray[i].length; j++) {
intArray[i][j] = (int)myArray[i][j]; // Cast to int
}
}
// Display the 2D Array in Console Window...
System.out.println(ls + "2D Integer Array Contents:");
for (int i = 0; i < intArray.length; i++) {
System.out.println("Row #" + (i+1) + ": " + Arrays.toString(intArray[i]));
}
}
User fills 2D Integer Array with Unique values throughout the entire Array:
// Setup for Keyboard input to Console.
Scanner input = new Scanner(System.in);
// System Line Separator used in console display.
String ls = System.lineSeparator();
// Declare and initialize a 2D Object Array.
// We need to use Object so that all initialized
// elements will be null rather than 0 since 0
// could be supplied and will need to be checked
// for Unique. Since a 2D int array by default
// initializes all elements to 0, a supplied 0
// will never be considered Unique.
Object[][] myArray = new Object[5][5];
// Have User fill our 2D Array...
for (int row = 0; row < myArray.length; row++) {
// Display the Row User will be on to fill.
System.out.println(ls + "Enter values for Row #" + (row+1) +
" of " + myArray.length);
// Allow User to fill each column of the current Row...
for (int column = 0; column < myArray[row].length; column++) {
// Flag to indicate Uniqueness.
boolean unique = false;
// Integer variable to hold what the User enters in console
int value = 0;
// Continue looping to ensure the User supplied a proper
// integer value which is unique to the ENTIRE 2D Array.
while (!unique) {
// Display the Column User will be on to fill.
System.out.print("Column #" + (column+1) + " value: --> ");
// Trap User entries that are not Integer values. If any alpha
// characters are supplied with the value then an exception is
// automatically thrown which we trap.
try {
// Get input from User...
value = input.nextInt();
} catch (Exception ex) {
// Inform the User of an improper entry if an exception was thrown.
System.err.println("You must supply an Integer value. Try again...");
input.nextLine(); // Clear Scanner buffer
// Allow User to try another entry for the same Column
continue;
}
// Flag to hold when a match is found. This flag will allow
// us to break out the the for loops faster
boolean match = false;
// See if value is already contained within the array.
// Iterate Rows...
for (int i = 0; i < myArray.length; i++) {
// Iterate the Columns for each Row...
for (int j = 0; j < myArray[i].length; j++) {
// Stop checking if we hit null. Nothing there yet.
if (myArray[i][j] == null) {
break;
}
// If a row's column element equals supplied value...
else if ((int)myArray[i][j] == value) {
match = true; // A match was detected - Not Unique
System.err.println("Value is not Unique - Try Again...");
break; // Break out of checking early
}
}
if (match) { break; } // Break out of outer loop is there was a match
}
unique = !match; // unique flag is to be oposite of what match contains
}
myArray[row][column] = value; // Add supplied value to array
}
}
// Convert the 2D Object Array to a 2D int Array
int[][] intArray = new int[myArray.length][myArray[0].length];
for (int i = 0;i < myArray.length; i++) {
for (int j = 0; j < myArray[i].length; j++) {
intArray[i][j] = (int)myArray[i][j]; // Cast to int
}
}
// Display the 2D Array...
System.out.println(ls + "2D Integer Array Contents:");
for (int i = 0; i < intArray.length; i++) {
System.out.println("Row #" + (i+1) + ": " + Arrays.toString(intArray[i]));
}

Java - Change one element in the grid presentation

The code I have now prints out a grid made from an array:
//some code that generates the array gameCards[] = {'a','a','a','a','b','b','b','b'}
//n is the size/length of the array
public String BoardToString(){
int gridCount = 1;
int cardCount = 0;
char[][] showBoard = new char[n/4][4];
while (cardCount < n){
for(int row = 0; row < (n/4); row++){
for(int column = 0; column < 4; column++){
showBoard[row][column] = gameCards[cardCount]; // also how can I use gameCards if it's generated in another method within the same class?
System.out.print("X (" + gridCount + ") ");
gridCount++;
cardCount++;
}
if ((n/4) > 1) System.out.println();
}
}
}
It will print out something like this:
// if n = 8
X(1) X(2) X(3) X(4)
X(5) X(6) X(7) X(8)
The presentation of the grid corresponds to the order of the elements in the original array. If I want to achieve something like this:
a(1) X(2) X(3) X(4)
X(5) X(6) X(7) X(8)
or
a(1) X(2) X(3) X(4)
X(5) b(6) X(7) X(8)
How should I write the loop so it can print out most of the masked grid and only showing 1 actual element (maximum element I need to reveal is 2)?
Basically you have to store coordinates of the card user picked. Then when printing a card check if it is the card user picked. If it is, print its letter instead of an X. Remember first choice and repeat the process for the second card. After second round clear the two cards you stored and repeat.
for(int column = 0; column < 4; column++){
showBoard[row][column] = gameCards[cardCount]; // also how can I use gameCards if it's generated in another method within the same class?
if (pickedRow1 == row && pickedCol1 == column || pickedRow2 == row && pickedCol2 == column) {
System.out.print(CARD_LETTER + " (" + gridCount + ") ");
} else {
System.out.print("X (" + gridCount + ") ");
}
gridCount++;
cardCount++;
}
For your second question. When you generate gameCards in the other method, either pass it to BoardToString as a parameter or you can store it to the instance variable and later access it in the BoardToString method.

Trying to count number of items in a 2d array

I am trying to find a comparable value that is common to all rows in a 2D array.
For that value, I'd like to find the minimal (> 0) number of repetitions that exist in all rows.
For example, when working with a 2D array of String:
{
{A, C, B},
{A, A, B},
{C, D, A}
}
The only value that exists in all rows is "A". The minimal number of appearances in a row is 1, so the answer would be 1 A.
Here is my code: I am trying to search each column in a row for duplicates (or triplets, etc.), determine the count for a given row and compare it to the other rows to determine the row with the lowest quantity. Also, maybe there is a more elegant approach? For some reason it is not working (Collections is a 2d String array):
public class CommonElements {
ArrayList<String> commonCollections = new ArrayList<String>();
private int comparisons = 0;
int i, j, k;
int count, lowestCount;
String previousString = "";
int row[];
String current;
public Comparable[] findCommonElements(Comparable[][] collections) {
Arrays.sort(collections[0]);
row = new int[collections[0].length];
for (i = 0; i < collections[0].length; i++) { // first row column selection
current = collections[0][i].toString();
lowestCount = 1;
for (j = 0; j < collections.length; j++) { // row
count = 0;
for (k = 0; k < collections[0].length; k++) { // column
if (current.equals(collections[j][k].toString())) { // if contains same string as first row column selected
count++;
System.out.print(count + "\n");
}
}
if (lowestCount < count) {
lowestCount = count;
}
}
}
System.out.print(lowestCount);
return collections[0];
}
public int getComparisons() {
return comparisons;
}
}
Well, first you take collections[0][i].toString() when i is 0 so that evaluates to A, then program goes through all those loops and lowestCount is set to 1. Then your first for loop moves on to B and lowestCount is reseted without it being saved anywhere. You should save your lowestCount perhaps in array or a list, and at the end of the first for loop (after 2 other for loops) add the lowestCount to that array and you will have the lowest count of every letter. If you don't want to save it you can just System.out.println("Lowest count of letter: "+current+" is: "+lowestCount);. If you want to determine the row with the lowest count you can also save it in array (row with lowest count for every letter) and set it in that if that if statement passes (if(lowestCount < count)).
I'm not sure if I understood you correctly, but there is definitely a better approach to solving this problem.
You can do like this
int[][] arr = new int[5][2];
int count =0;
for(int[] i : arr){
count = count + i.length;
}
System.out.println(count);

Storing contents of a webtable in a 2d matrix

I am trying to get the contents of a webtable using selenium and then store the contents in a 2d matrix.
Below is my code :
//Locate the webtable
WebElement reportTable = driver.findElement(By.xpath("//*[#id='pageContainer']/div/div[2]/table[2]"));
int rowCount = driver.findElements(By.xpath("//*[#id='pageContainer']/div/div[2]/table[2]/tbody/tr")).size(); //Get number of rows
System.out.println("Number of rows : " +rowCount);
String[][] reportMatrix = new String[rowCount-1][]; //Declare new 2d String array
//rowCount-1 because the first row is header which i don't need to store
int mainColCount = 0;
for(int i=2;i<=rowCount;i++) //Start count from second row, and loop till last row
{
int columnCount = driver.findElements(By.xpath("//*[#id='pageContainer']/div/div[2]/table[2]/tbody/tr["+i+"]/td")).size(); //Get number of columns
System.out.println("Number of columns : " +columnCount);
mainColCount = columnCount;
for(int j=1;j<=columnCount;j++) //Start count from first column and loop till last column
{
String text = driver.findElement(By.xpath("//*[#id='pageContainer']/div/div[2]/table[2]/tbody/tr["+i+"]/td["+j+"]/div")).getText(); //Get cell contents
System.out.println(i + " " + j + " " + text);
reportMatrix[i-2][j-1] = text; //Store cell contents in 2d array, adjust index values accordingly
}
}
//Print contents of 2d matrix
for(int i=0;i<rowCount-1;i++)
{
for(int j=0;j<mainColCount;j++)
{
System.out.print(reportMatrix[i][j] + " ");
}
System.out.println();
}
This gives me a Null Pointer Exception at "reportMatrix[i-2][j-1] = text".
I don't understand what I am doing wrong. Do I have to give even the second index when I declare the 2d array ?
Thanks in advance.
Unless you're a student who is studying multi-dimensional arrays, or you are otherwise constrained by an API you're required to use, just avoid arrays. You'll stay saner longer :)
If you HAVE to use a 2D array, it's wise to remember that you are not actually creating a matrix. You are creating a 1D array, and each element of this array is another 1D array. When you think of it that way, it becomes clear that you definitely have to initialize the "columns" arrays as well as the "rows" array.
This line:
String[][] reportMatrix = new String[rowCount-1][];
will initialize report matrix to have rowCount - 1 rows, and null for each and every set of columns.
Inside your first loop, after you have identified the number of columns, you want to do something like so:
reportMatrix[i] = new String[columnCount];
for(int j=1;j<=columnCount;j++) ...
This will allow you to have different number of columns in each row, if necessary.
Then, in your print loop, you should use the array lengths to print out the rows and columns. Remember to subtract 1 from the length attribute, since the this represents the number of elements in the array, and we almost always use zero-indexed for loops.
//Print contents of 2d matrix
for(int i=0; i < reportMatrix.length - 1; i++)
{
for(int j=0; j < reportMatrix[i].length - 1; j++)
{
System.out.print(reportMatrix[i][j] + " ");
}
System.out.println();
}

Remove every 3rd element in arraylist

I am trying to loop through an arraylist and gradually remove an element every 3 indices. Once it gets to the end of the arraylist I want to reset the index back to the beginning, and then loop through the arraylist again, again removing an element every 3 indices until there is only one element left in the arraylist.
The listOfWords is an array with a length of 3 that was previously filled.
int listIndex = 0;
do
{
// just to display contents of arraylist
System.out.println(listOfPlayers);
for(int wordIndex = 0; wordIndex < listOfWords.length; wordIndex++
{
System.out.print("Player");
System.out.print(listOfPlayers.get(wordIndex));
System.out.println("");
listIndex = wordIndex;
}
listOfPlayers.remove(listOfPlayers.get(listIndex));
}
while(listOfPlayers.size() > 1);
I have tried to implement for several hours yet I am still having trouble. Here's what happens to the elements of the arraylist:
1, 2, 3, 4
1, 2, 4
1, 2
Then it throws an 'index out of bounds error' exception when it checks for the third element (which no longer exists). Once it reaches the last element I want it to wrap around to the first element and continue through the array. I also want it to start where it left off and not from the beginning once it removes an element from the arraylist.
Maybe I have just missed the boat, but is this what you were after?
import java.util.ArrayList;
import java.util.Random;
public class Test {
public static void main(String[] args) {
ArrayList<Integer> numbers = new ArrayList<Integer>();
Random r = new Random();
//Populate array with ten random elements
for(int i = 0 ; i < 4; i++){
numbers.add(r.nextInt());
}
while(numbers.size() > 1){
for(int i = 0; i < numbers.size();i++){
if(i%3 == 0){//Every 3rd element should be true
numbers.remove(i);
}
}
}
}
}
You could move every third element to a temporary list then use List#removeAll(Collection) to remove the items when you finish each loop...until the master list was empty...
Lets back up and look at the problem algorithmically.
Start at the first item and start counting.
Go to the next item and increment your count. If there is no next item, go to the beginning.
If the count is '3', delete that item and reset count. (Or modulo.)
If there is one item left in the list, stop.
Lets write pseudocode:
function (takes a list)
remember what index in that list we're at
remember whether this is the item we want to delete.
loop until the list is size 1
increment the item we're looking at.
increment the delete count we're on
should we delete?
if so, delete!
reset delete count
are we at the end of the list?
if so, reset our index
Looking at it this way, it's fairly easy to translate this immediately into code:
public void doIt(List<String> arrayList) {
int index = 0;
int count = 0;
while(arrayList.size() != 1) {
index = index + 1;
count = count + 1; //increment count
String word = arrayList.get(index);//get next item, and do stuff with it
if (count == 3) {
//note that the [Java API][1] allows you to remove by index
arrayList.remove(index - 1);//otherwise you'll get an off-by-one error
count = 0; //reset count
}
if (index = arrayList.size()) {
index = 0; //reset index
}
}
}
So, you can see the trick is to think step by step what you're doing, and then slowly translate that into code. I think you may have been caught up on fixing your initial attempt: never be afraid to throw code out.
Try the following code. It keeps on removing every nth element in List until one element is left.
List<Integer> array = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
int nth = 3;
int step = nth - 1;
int benchmark = 0;
while (array.size() > 1) {
benchmark += step;
benchmark = benchmark > array.size() - 1 ? benchmark % array.size() : benchmark;
System.out.println(benchmark);
array.remove(array.get(benchmark));
System.out.println(array);
}
You could use a counter int k that you keep incrementing by three, like k += 3. However, before you use that counter as an index to kick out any array element, check if you already went beyond and if so, subtract the length of this array from your counter k. Also make sure, to break out of your loop once you find out the array has only one element left.
int k = -1;
int sz = list.length;
while (sz > 1)
{
k += 3;
if (k >= sz)
{
k -= sz;
}
list.remove(k);
sz --;
}
This examples shows that you already know right away how often you will evict an element, i.e. sz - 1 times.
By the way, sz % 3 has only three possible results, 0, 1, 2. With a piece of paper and a cup of coffee you can find out what the surviving element will be depending on that, without running any loop at all!
You could try using an iterator. It's late irl so don't expect too much.
public removeThirdIndex( listOfWords ) {
Iterator iterator = listOfWords.iterator
while( iterator.hasNext() ){
iterator.next();
iterator.next();
iterator.next();
iterator.remove();
}
}
#Test
public void tester(){
// JUnit test > main
List listOfWords = ... // Add a collection data structure with "words"
while( listOfWords.size() < 3 ) {
removeThirdIndex( listOfWords ); // collections are mutable ;(
}
assertTrue( listOfWords.size() < 3 );
}
I would simply set the removed to null and then skip nulls in the inner loop.
boolean continue;
do {
continue = false;
for( int i = 2; i < list.length; i += 3 ){
while( list.item(i++) == null && i < list.length );
Sout("Player " + list.item(--i) );
continue = true;
}
} while (continue);
I'd choose this over unjustified shuffling of the array.
(The i++ and --i might seem ugly and may be rewritten nicely.)

Categories