Iterating through all slots that are not null, 2d array? - java

I must work with a 2d array. The maximum length of the row slots in the array is 100. More often than not, anywhere from 5-20 of these array slots will be filled and not more, however, I must build my code to a max of 100 rows. My question is, is there a way to iterate through only the array slots that have been set, stopping before the last unset, null slots?
//initialize array
String[][] variables = new String[numVariables][100];
//System.out.printf("%s \n", numVariables);
for(int i=0; i < numVariables; i++){
//reads in variable line
String variableLine = fin.nextLine();
//turn variable line into array
varArray = variableLine.split(" ");
numRules = Integer.parseInt(varArray[0].replaceAll("\\s",""));
for(int j=0; j < numRules+1; j++){
variables[i][j] = varArray[j+1];
System.out.printf("%s ", variables[i][j]);
}
System.out.println("\n");
}
//**LATER IN MY CODE ****//
//ITERATE THROUGH 'variables' array and PRINT OUT ONLY VALUES THAT ARE SET

If you populate the array in order from 0 to 100. If the first 51 elements are populated with the string then you could use:
for(int i=0; i < numVariables; i++){
for(int j=0; j < numRules+1; j++){
if (variables[i][j] == null)
break;
System.out.printf("%s ", variables[i][j]);
}
}

Why do you even store the nulls if you don't need them? A String[][] is an array of arrays of String - those inner arrays need not have the same length. You could therefore create each inner array with the number of elements it needs:
//initialize array
String[][] variables = new String[numVariables][];
//System.out.printf("%s \n", numVariables);
for(int i=0; i < numVariables; i++){
//reads in variable line
String variableLine = fin.nextLine();
//turn variable line into array
varArray = variableLine.split(" ");
numRules = Integer.parseInt(varArray[0].replaceAll("\\s",""));
variables[i] = Arrays.copyOfRange(varArray, 1, numRules - 1);
}
and then iterate:
for (String[] var : variables) {
for (String s : var) {
System.out.print(s);
}
System.out.println();
}

You can either use an array of List<String> or you can also keep track of the length of all your rows.
int [] rowLength = new int[numVariables]
for(int i=0; i < numVariables; i++){
/* ... */
numRules = Integer.parseInt(varArray[0].replaceAll("\\s",""));
// store the number of slots in variable[i]
rowLength[i] = numRules+1;
/* ... */
}
Then you iterate only from zero to the length of your row (rowLength[i]).
A third approach (and the one I would prefer) is to not specify the length of the row slots in your array :
String [][] variables = new String[numVariables][];
Then after having calculated numRules:
variables[i] = new String[numRules+1];

Given the situation you have described you'd probably be better off using another data structure, but seeing as you cannot you could keep a record of what values have been changed.
So you could keep an array of the length of each row and end each search there for the row.
String[][] variables = new String[numVariables][100];
int rowLength[] = new int[numVariables];
//...
// get and record the rowLength
//...
for(int x=0; x < numVariables; x ++) {
for(int y=0; y < rowLength[x]; y ++) {
// do your stuff
}
}
}
Or you could use a map or ArrayList to keep track of each of the positions that contain numbers.

Related

Find the maximum of the length of 2 arrays

I am passing 2 arrays to the controller with different lengths, I want to execute a for loop and length of that will be the max of the length of 2 arrays.
I am not getting how to execute that. I tried Math.max but its giving me error as cannot assign a value to the final variable length.
String[] x =0;
x.length = Math.max(y.length,z.length);
for(int i=0; i < x.length; i++)
The no of elements in x and y are not fixed. it changes what we are passing from the front end.
Initialize the new array with the desired length:
String[] x = new String[Math.max(y.length,z.length)];
In case you don't need to create an array, just use the result of Math.max as conditional to stop your loop:
for (int i = 0; i < Math.max(y.length,z.length); i++) {
//...
}
Just bring your Math.max() operation into the array's initialization.
String[] x = new String[Math.max(y.length, z.length)];
Here's an expansion for clarity:
int xLength = Math.max(y.length, z.length);
String[] x = new String[xLength];
Edit: Unless, OP, you're not interested in creating another array...
I want to execute a for loop and length of that will be the max of the length of 2 arrays
Just bring your Math.max() operation into your for loop:
for(int i=0; i < Math.max(y.length, z.length); i++){
//code here
}
Set a variable to the maximum length of the arrays, create a new array with that length and then loop until that point.
int maxLen = Math.max(y.length, x.length);
String[] array = new String[maxLen];
for(int i = 0; i < maxLen; i++){
// Loop code here
}
int max_length = Math.max(y.length,z.length);
for(int i=0; i < max_length ; i++){
//...
}
you can use that max_length to create a new String[] if you are trying to create an array with total length of y and z arrays, like
String[] newArray = new String[max_length];

Why, when I am transferring elements from 1d array to 2d array, on getting the last 1d array made from previous loop

while (scanner.hasNextLine()) {
line = scanner.nextLine();
if (line.charAt(0) != '#') {
c++;
//looking to get dimensions of line segments from file.
dimensions = new int[c][4];
//Split my file input into an array of tokens(strings)
tokens = line.split(",");
for (int i = 0; i < tokens.length; i++) {
//Parse strings to int.
dimtoke[i] = Integer.parseInt(tokens[i]);
for (int k = 0; k < dimensions.length; k++) {
for (int j = 0; j < dimensions[0].length; j++) {
//attempt to fill 2d array with contents from file.
dimensions[k][j] = dimtoke[j];
}
}
}
}
}
I get a 2d array full of the last dimension in the file instead of all the dimensions. The dimensions come in groups of 4 in a single line of text, so i made a single array with those tokens from each line i read in from the file so i could parse them to ints. something is happening in the process of transferring the 1d array of ints to the 2d array.
You have to close {} the tokens loop like this:
for (int i = 0; i < tokens.length; i++) {
//Parse strings to int.
dimtoke[i] = Integer.parseInt(tokens[i]);
}//you need a closing here
for (int k = 0; k < dimensions.length; k++) {
for (int j = 0; j < dimensions[0].length; j++) {
//attempt to fill 2d array with contents from file.
dimensions[k][j] = dimtoke[j];
}
}
I'll try to explain it to you.
Everytime you get an int in tokens with the instruction
dimtoke[i] = Integer.parseInt(tokens[i]);
Before getting the next int in dimtoke[i+1] you get into a loop where you fill all the ints in the 2d array with that dimitoke[i].
When those loops have finished(all the 2d array has been filled with only 1 int), you go again up and fill the dimitoke with the next int, and again, fill all the 2d array with that int.
What you need to do is to first finish the for loop and fill the dimitoke with the whole set of ints, and then, fill the 2D array with the ints in dimitoke.
Your problem was that you filled the whole array everytime you put an int in dimitoke, so everytime the whole 2d array was overwritten with only 1 int.
Another thing I expect to be wrong:
When you are filling the 2D array, you put the j variable in both dimensions and dimitoke, so if dimitoke lenght is not equal than the second array lenght of dimensions, you'll fill again every row with the same if dimitoke is greater, and indexOutOfBounds Excepcion if it's lesser. Here's an example:
dimitoke dimension = 10 = {0,1,2,3,4,5,6,7,8,9}
if dimensions have dimension 4, the output of dimensions will be:
0,1,2,3
0,1,2,3
0,1,2,3
.
.. c rows.
To repair that, what you can do is to change the dimitoke variable for a int n (for example) and change the code like this:
int n =0;
for (int k = 0; k < dimensions.length; k++) {
for (int j = 0; j < dimensions[0].length; j++) {
//attempt to fill 2d array with contents from file.
dimensions[k][j] = dimtoke[n];
n++;
}
}
I hope the error is out now
Not completely know what you want to do. But I think you should separate the two loop:
assign value to the dimtoke.
assign value to dimensions.
So I think apparently, you should enclose the loop here:
for (int i = 0; i < tokens.length; i++) {
//Parse strings to int.
dimtoke[i] = Integer.parseInt(tokens[i]);
}

Appending to double Array method

So, I have a method like this
public String[][] getArgs(){
And, I want it to get results out of a for loop:
for(int i = 0; i < length; i++){
But how do I append them to the array instead of just returning them?
Create a String[][] array inside your method, fill this array inside a loop (or in any other way) and return that array in the end.
If you are sure you want to have only one for loop (instead of two, typical for 2-dimensional array), ensure your loop will go through the number of examples equal to the number of fields in your String[][] array. Then you can calculate the double-dimension array indexes from your single loop-iterator, for example:
for(int i = 0; i < length; i++){
int a = i % numberOfCollumnsInOutput;
int b = i / numberOfCollumnsInOutput;
String[a][b] = sourceForYourData[i];
}
(Of course which array dimension you treat as collumns (and which to be rows) depends on yourself only.) However, it is much more typical to go through an n-dimensional array using n nested loops, like this (example for 2d array, like the one you want to output):
for(int i = 0; i < dimensionOne; i++){
for(int j = 0; j < dimensionTwo; j++){
array[i][j] = someData;
}
}
For your interest. A sample code according to Byakuya.
public String[][] getArgs(){
int row = 3;
int column =4;
String [][] args = new String[row][column];
for(int i=0;i<row;i++)
for(int j=0;j<column;j++)
args[i][j] = "*";
return args;
}
You can make a LinkedList from that array, and then append the elements to it, and then create a new array from it. If you are not sure i'll post some code.

Java loop output keep on repeating

String[] month = {"Jan","Feb","Mar","Apr","May","June","July","Aug","Sept","Oct","Nov","Dec"};
int[] monthArray = new int[12];
String[][] itemArray = new String[12][10];
Variables
monthArray[i] = input.nextInt();
itemArray[monthArray[i]-1][e] = input.next();
Store a maximum of 5 String values on user input's month.
for(int i=0;i<e;e++){
System.out.println(itemArray[monthArray[i]-1][i]);
}
Having a problem displaying the String values (it just keep repeating the first String value) under user input's month.
You are increasing e instead of i in the last loop. e is the limit and not the variable you use for the iteration and thus the loop will not terminate until you overflow int.
for(int i = 0; i < e; i++ /* Note the usage of i here*/) {
use i++ instead of e++
here e stands for the limit
and i stands for the variable.
Since you have a 2D array, maybe you want something more like this, to print out the values, once, the array has been populated.
String[][] itemArray = new String[12][10];
for(int i = 0; i < itemAreray.length; i++){
for (int j = 0; j < itemArray[i].legnth; j++){
System.out.println(itemArray[i][j]);
}
}
Unless you're having difficulty populating the array. Then that's a different problem

First Element in TwoDimensional Array goes to null?

I am using this code to insert the details in to TwoDimensional Array. But while retrieving the data from the array the first element value changes to null.
Cursor consultancy = db.getConsultancy(this);
if(consultancy!=null)
{
consultancy.moveToFirst();
consultancy.moveToNext();
consultancynames = new String[(int) db.getConsultancyCount()-1];
for(int i=0;i<db.getConsultancyCount()-1;i++)
{
consultancynames[i] = consultancy.getString(2);
int consultantid = Integer.parseInt(consultancy.getString(consultancy.getColumnIndex(TimeAndExpensesLocalDB.CT_CONSULTANCYID)));
Cursor project_namecur = db.getProjectCode(this, consultantid);
if(project_namecur!=null)
{
project_namecur.moveToFirst();
projectname = new String[(int) db.getConsultancyCount()][project_namecur.getCount()];
for(int j=0;j<project_namecur.getCount();j++)
{
projectname[i][j] = project_namecur.getString(3);
project_namecur.moveToNext();
}
}
consultancy.moveToNext();
}
}
//... Print array
for (int i =0; i < consultancynames.length; i++) {
for (int j = 0; j < projectname.length; j++) {
System.out.print(" " + projectname[i][j]);
}
System.out.println("");
}
Output
05-25 12:58:22.700: I/System.out(2373): null null null
05-25 12:58:22.700: I/System.out(2373): Other-1 Other-2 Other-3
I am not sure what is happening.
Thanks for your help guys..
You're creating a new array on each iteration of the loop:
projectname = new String[(int) db.getConsultancyCount()][project_namecur.getCount()];
So on the first iteration you're creating an array and filling in the first "row" of the array. On the second iteration you're creating a new array (which will default to having null elements) and filling in the second row.
I suspect you need to allocate the "outer" array once before the loop, then allocate the "inner" array based on how many project names there are for that consultant:
// Note: more idiomatic names would be consultancyNames and
// projectNames. It's also unclear why you're subtracting one from the count...
consultancynames = new String[(int) db.getConsultancyCount() - 1];
projectnames = new String[consultancynames.length][];
for (int i = 0;i< consultancenames.length; i++) {
...
projectnames[i] = new String[project_namecur.getCount())];
...
}
Then you'll need to change your display code too, e.g. to
for (int i =0; i < projectname.length; i++) {
for (int j = 0; j < projectname[i].length; j++) {
System.out.print(" " + projectname[i][j]);
}
System.out.println("");
}
Note that you can't do the following:
projectname = new String[(int) db.getConsultancyCount()][project_namecur.getCount()];
for(int j=0;j<project_namecur.getCount();j++)
{
projectname[i][j] = project_namecur.getString(3);
project_namecur.moveToNext();
}
Here's why:
After the first line projectname will be an array of arrays.
Since the arrays are object references you have an array of object references.
Since the default value of an object reference is null, you'll have an array of null elements.
This means you can't do
projectname[i][j] = project_namecur.getString(3);
since it corresponds to
String[] row = projectname[i];
// row == null !
row[j] = project_namecur.getString(3);

Categories