2D array not printing the last element during comparison - java

I am trying to replace rows from an original 2d array to a updated 2d array. Problem is it won't store the last element during the replacement.
Here's my code:
String[][] updatedArray = {{"red","a","b","c"},{"yellow","a","b","c"}, {"purple","a","b","c"}};
String[][] originalArray = {{"red","aa","bb","cc"},{"yellow","ww","vv","zz"}, {"green","yy","uu","pp"}, {"purple","nn","mm","bb","hello"}};
for (int i = 0; i < updatedArray.length;i++ ) {
for (int j = 0; j < updatedArray[i].length; j++){
for(int x = 0; x < originalArray.length;x++){
for(int z = 0; z < originalArray[x].length;z++){
if(originalArray[x][0].equals(updatedArray[i][0])) {
updatedArray[i][j] = originalArray[x][j];
System.out.println("There's a match!!");
}else{
System.out.println("No match!");
}
}
}
}
}
System.out.println("originalArray:");
System.out.println(Arrays.deepToString(originalArray));
System.out.println("updatedArray:");
System.out.println(Arrays.deepToString(updatedArray));
For example, initially updatedArray in last row "purple" has {"purple","a","b","c"}. When it does the replacement using values from originalArray, the code above only outputs:
... [purple, nn, mm, bb]
which is wrong because it doesn't add the last element "hello". It should output:
... [purple, nn, mm, bb, hello]
I am aware the problem is in this line:
updatedArray[i][j] = originalArray[x][j];
Problem is no matter what I try to change originalArray[x][j] to originalArray[x][z] ... its screws up everything.
Any ideas on this? Still trying to get the jist of 2D arrays.

If there is a match, instead of trying to set each element in the updatedArray to the corresponding element in the original array you can just set the entire array to the original array.
String[][] updatedArray = {{"red","a","b","c"},{"yellow","a","b","c"}, {"purple","a","b","c"}};
String[][] originalArray = {{"red","aa","bb","cc"},{"yellow","ww","vv","zz"}, {"green","yy","uu","pp"}, {"purple","nn","mm","bb","hello"}};
for (int i = 0; i < updatedArray.length;i++ ) {
for (int j = 0; j < originalArray.length; j++){
if(originalArray[j][0].equals(updatedArray[i][0])) {
updatedArray[i] = originalArray[j];
System.out.println("There's a match!!");
}else{
System.out.println("No match!");
}
}
}

The issue is how you chose to iterate over the dimensions of updatedArray which are different than the dimensions of originalArray.
Let just look at the case i=2 which is the 'row' for purple:
for (int j = 0; j < updatedArray[i].length; j++){
updatedArray[i=2].length = 4
in updated:
index = 0 , 1 , 2 , 3
{"purple","a","b","c"}
in original:
index = 0 , 1 , 2 , 3 , 4
{"purple","nn","mm","bb","hello"}
Therefore since j will always be < 4 it can never be used to index originalArray[x][4] = "hello"
DANGER: this code also doesn't handle the fact that you would need to extend the purple array for updatedArray. Java may do some magic to handle this for you but I wouldn't trust it to work that way.
Suggestion:
- compare the lengths of each row and allocate extra memory where necessary before copying data from originalArray to updatedArray
- if possible just copy the whole row between original and updated.

Related

Taking data from one array to create another. What's wrong with this loop?

I am working on an assignment where I need to create two arrays, then look through them and create a new array that holds any values inside of both the first two. Originally, I was close to accomplishing this by making an arraylist but my lab professor told me that wasn't allowed so I needed to re-start and didn't have enough time to figure out the solution.
If you'd like to see the whole code I have now: http://pastebin.com/thsYnj2z
I am really struggling with this loop here:
for(int i = 0 ; i < Xarr.length ; i++){
for(int j = 0 ; j < Yarr.length ; j++)
//Compare. If the two are the same, they go inside of A.
if (Xarr[i] == Yarr[j]){
ArrA[k] = Xarr[i];
k++;
System.out.println(ArrA[k]);
break;
}
My output is remaining 0 for my ArrA[k] array. I can't seem to trouble shoot this issue on my own.
try making these changes
for(int i = 0 ; i < Xarr.length ; i++){
for(int j = 0 ; j < Yarr.length ; j++)
//Compare. If the two are the same, they go inside of A.
if (Xarr[i] == Yarr[j]){
ArrA[k] = Xarr[i];
System.out.println(ArrA[k]); // or print them all later
k++;
break; // break to outer loop
}
}
}
note
Assuming OP has correctly initialized ArrA
note2
Assuming that only unique values are required, hence the breaking
Does your solution require that no values are duplicated in ArrA? Or are duplicate values allowed? For example, if some values occur multiple times in each array, you could get multiple matches on the same number.
If duplicates aren't a problem:
for(int i = 0 ; i < Xarr.length ; i++){
for(int j = 0 ; j < Yarr.length ; j++){
//Compare. If the two are the same, they go inside of A.
if (Xarr[i] == Yarr[j]){
ArrA[k] = Xarr[i];
System.out.println(ArrA[k]);
k++;
}
}}
As I understand it, the problem is to take 2 arrays, and produce a third array which is a Union of the first 2. Union of 2 sets being the subset of the values found in both sets.
Your code was missing some braces, so put those back in there. Also you wont want to print the k+1th item after you just put a value in ArrA[k] im assuming.
Otherwise you were pretty much there. The break terminates the inner loop and allows the outer loop to increment i and continue on. This is because you have already found a match, no need to continue searching, just move onto the next index in Xarr.
Algorithm goes like this: For each value in X, search Y for a match. If it is found, add this value to A.
for(int i = 0 ; i < Xarr.length ; i++) {
for(int j = 0 ; j < Yarr.length ; j++) {
//Compare. If the two are the same, they go inside of A.
if (Xarr[i] == Yarr[j]){
ArrA[k] = Xarr[i];
System.out.println(ArrA[k]);
k++; //you probably want to increment k after you add to ArrA, not before
break;
}
}
}
public static void main(String... args){
int[] xArr = {1, 1,1,1,1,1};
int[] yArr = {1, };
int[] kArr = new int[xArr.length > yArr.length ? xArr.length : yArr.length];
int k = 0;
for(int x = 0; x < xArr.length; x++){
for(int y = 0; y < yArr.length; y ++){
int xNum = xArr[x];
int yNum = yArr[y];
if(xNum == yNum) kArr[k++] = xNum;
}
}
int[] resizedKArr = new int[k];
for(int i = 0; i < resizedKArr.length; i++) resizedKArr[i] = kArr[i];
Arrays.sort(resizedKArr);
for(int x : resizedKArr) System.out.println(x);
}
First, xArr and yArr are given some random numbers, and then kArr is initialized with the size of the lagest array we are comparing with to ensure the array has enough space to hold similar values.
Then, in the next section we do a loop inside of a loop to compare the values against each other and if they are similar then k++ and set the next value in the array. This goes on until the loops are completed, notice there really is never a need to break from either loop until all values are compared. At that point the loops break themselves and move on to the next bit of code.
The last section is just to create an array of the same size as k and move the values over, I don't know the requirements of your studies, although when using primitives like this you may want to do this in case you have a matching 0 as a number. Otherwise you'll have a ton of 0s filling the empty spaces of your array.
And lastly, we just sort the array for good measure and print it out.
Hope I've answered your question and you get something out of this post!
The problem is printing ArrA[k] after k++. Try increasing line after print.

Arrays in array, 100 rows, dynamic columns

I'm trying to get this:
arrays[1][0] = 5
arrays[2][0] = 7
arrays[2][1] = 2
arrays[3][0] = 6
arrays[3][1] = 9
arrays[3][2] = 11
So I want arrays[1][] to have one element of random data, arrays[2][] to have 2 elements of random data and so on until I have 100 arrays. So my last array would be arrays[100][] with 100 elements of random data.
This is the code I have now but I get a NullPointerException when arrays[i][j] = generator.nextInt(max) is executed:
Comparable[][] arrays = new Comparable[100][];
for (int i=1; i<101;i++){
for (int j=0; j <= i-1; j++){
arrays[i][j] = generator.nextInt(max);
}
}
Your
Comparable[][] arrays = new Comparable[100][];
line only creates the outermost array. You need to create the arrays that go in it, e.g. something like this:
Comparable[][] arrays = new Comparable[100][];
for (int i=1; i<101;i++){
arrays[i] = new Comparable[/* relevant length here*/]; // <====
for (int j=0; j <= i-1; j++){
arrays[i][j] = generator.nextInt(max);
}
}
It's unclear to me why you start i at 1 or where the randomness should be (I'm guessing at /* relevant length here */), but hopefully that points you the right way.

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]);
}

I can't see what's wrong with my Java code?

I am making a program that puts all data from one array, into a different array, backwards.
So, if
String[] originalArray = {"you", "see", "I"};
then it should transfer that into a new array like this:
String[] newArray = new String[3];
newArray = "I", "see", "you"
Here's my code.
public class ReverseArray {
public static void reverse() {
String[] originalArray = {"cool", "really", "are", "You"};
String[] newArray = {"", "", "", ""};
for(int b = 0; b < newArray.length; b++) {
for(int a = 3; a < -1; a--) {
newArray[b] = originalArray[a];
}
}
for(int c = 0; c < newArray.length; c++) {
System.out.print(newArray[c] + "+");
}
}
}
I'm not sure what is wrong. When I try to print it out, it just prints out (+ + + +)
I've tried changing
String[] newArray = {"", "", "", ""};
to
String[] newArray = new String[4];
But it just made then output as
null
Any help?
Your problem is in your inner loop...
for (int a = 3; a < -1; a--) {
Read this out loud...
a equals 3
while a is less than -1 do a--
See where it falls down, the for-loop will only run while a is -1, but you've initialised it to 3
You can actually get away with a single loop, for example...
String[] newArray = new String[originalArray.length];
for (int index = 0; index < newArray.length; index++) {
newArray[index] = originalArray[originalArray.length - index - 1];
}
Basically this uses the index value for both arrays, but adjust the originalArray so it moves from the end instead of the start, as one possible solution ;)
An alternative way using Collections.reverse():
List<String> list = Arrays.asList("cool", "really", "are", "You");
System.out.println(list);
Collections.reverse(list);
System.out.println(list);
Output:
[cool, really, are, You]
[You, are, really, cool]
Okay, so the steps are the following:
You have an array A of size X. You want to put these elements in an array B of size X. So basically what you want is that the element in A[0] (the first element) is in the last position of B, being B[2]. To do this, you need to calculate the "reverse" index.
So first you loop over your array:
for(int index = 0; index < A.length;index++)
{
String thisElement = A[index];
}
Next, you want to put it in the other array at the last position, right? So then you need to take the length of that array, minus the current index.
for(int index = 0; index < A.length;index++)
{
String thisElement = A[index];
// The other index
int otherIndex = (B.length - 1) - index; // We do -1 because we have zero-indexing.
B[otherIndex] = thisElement;
}
This should now contain all your elements in reverse order.
Some things you did wrong
I've tried changing
String[] newArray = {"", "", "", ""};
to
String[] newArray = new String[4];
These things are basically the same. The latter tells the compiler "Give me room for 4 strings". In the former you give it 4 strings and it makes room for them. So that's not really necesarry, but correct.
for(int b = 0; b < newArray.length; b++) {
for(int a = 3; a < -1; a--) {
newArray[b] = originalArray[a];
}
}
This piece of code is quite wrong as well. You walk over your array in the outer loop. And for each element you try to loop again. That is not needed either. Even so, your loop goes from 3 to 2 to ... But the condition is "as long as a is smaller than -1". It is not smaller than -1 to start with, so this loop will never execute.
You have big problems in your code here:
for(int b = 0; b < newArray.length; b++) {
for(int a = 3; a < -1; a--) {
newArray[b] = originalArray[a];
}
}
With "a < -1" you probably wanted "a > -1" otherwise the inner loop does not start. But most importantly you have two nested loops (two for loops) which doesn't make sense, you need only one for loop two reverse an array and you don't even need the new array to put the result:
for (i = 0; i < originalArray.length / 2; i++) {
int temp = originalArray[i];
originalArray[i] = originalArray[originalArray.length - 1 - i];
originalArray[originalArray.length - 1 - i] = temp;
}
This for loop works from both sides of the array inwards replacing the positions.
When you reach code mastery (or are not required to provide your own algorithm) you'll just use:
Collections.reverse()
:)

Java integer array, I cant do simple maths it seems

I have the code below:
int lines = 0;
while(lines < 2)
{
int[] oldarr = parr;
for(int i = 0; i < arrsize; i++)
System.out.print(" " + oldarr[i]);
System.out.println();
for(int i = 0; i < arrsize; i++)
{
if(i == 0)
parr[i] = 0;
else
parr[i] = Math.abs(oldarr[i] - oldarr[i-1]);
}
lines++;
}
parr is an array of integers of size [arrsize]. Each time through this loop I want to print the value of each index in parr, then set each index to the difference between the index before it and itself. Currently it gives me the correct (hardcoded) originally parr. But the next(first) iteration of changing parr gives me unexpected values; they are not even close to the difference between the two neighboring values..
Any ideas?
You aren't copying your array with this line:
int[] oldarr = parr;
The two variables are still pointing at the same array.
To get a copy, you can do:
int[] oldarr = Arrays.copyOf(parr, parr.length);
In your second for loop, you are setting the new value to the difference of the current value and the previous value, but the previous value was already changed in the previous iteration of the for loop.
Change your second for loop iteration to iterate through the array backwards, so your calculations don't depend on previous calculations.
for(int i = arrsize - 1; i >= 0; i--)

Categories