Home > Mobile >  How to find adjacent in a 2D array, after finding return its value
How to find adjacent in a 2D array, after finding return its value

Time:08-07

For this assessment, I am trying to read in a 2D array, read in and do calculations. I've got everything done, except for finding the adjacent value and if it's true, print yes and if not, print no. Adjacent, meaning that the values are right next to each other. I need to write a method that does the validation (whether if there are two or more values that are the same next to each other), return it, and then compare to see if there are two or more numbers that are the same. So far, the most difficult part is writing the code that checks for adjacent value. Each time I do, I either get a indexOutOfBond Exception thrown at me.

Just to reiterate if anything is not clear, I am just checking whether each row has two or more consecutive numbers and if there is, print yes. So far, here are some codes that I have written myself. I have done extensive research but I cannot seem to find anything that's resourceful, or maybe I am not looking at the right source.

Basically, here is my set of data (I made them up for testing) that I am supposed to validate. For example, the second row has 35 (right next to each other) so I am supposed to print yes. Same goes for the fifth row, I am also supposed to print 'yes' because it has 51 twice. It's not supposed to print yes for the first row, although it has 23 twice, the numbers are not next to each other so I cannot simply run a nested for loop.

https://prnt.sc/ppeytuizwWEt is the set of data. In case links are not allowed, data is also provided here.

[23, 14, 42, 34, 23] // although 23 shows nice, not consecutive
[35, 35, 42, 28, 38] // print yes
[35, 34, 45, 46, 47]
[40, 43, 35, 50, 49]
[21, 33, 10, 51, 51] // print yes, because 51 shows twice. 

How can I achieve this using the boolean method? I also know if the last row is true then all values might be true despite some rows being false.

public static void validation(int[][] array) {
    System.out.println();
    int i = 0;
    for (int[] element : array) {
        while (i < array.length) {
            if (i > 0) {
                if (element[i] == element[(i - 1)]) {
                    System.out.println("founded");
                }
            }
            i  ;
        }
    }
}

I've written more methods, the actual instruction is to write a method, return and then call the method onto another method and validate. So far, I am stuck writing the method that even checks for adjacent numbers. I found out that some methods I wrote only checks for duplicates.

public static void secondValidation(int[][] array) {
    int Duplicate = 0;
    for (int element[] : array) {
        for (int i = 0; i < array.length; i  ) {
            for (int j = 1; j < array.length; j  ) {
                if (element[j] == element[j - 1]) {
                    Duplicate = element[i];
                }
            }
        }
    }
    System.out.println(Duplicate);
}

I use void just for testing, but the instructions said to write a method alone for looking out for adjacent values.

public static boolean isValid(int[][] array) {
    boolean test = false;
    for (int[] element : array) {
        for (int i = 0; i < array.length; i  ) {
            for (int j = 0; j < array.length; j  ) {
                if (element[i] == element[i   1]) {
                    test = true;
                }
            }
        }
    }
    return test; // triple for loop didn't make sense but I included still. 
}

I've also tried this, I know the code is getting repetitive.. but I just wanted to try and I know I still have a lot to learn. If there is anything wrong with my post, please let me know.

public static void fourthValidation(int[][]array){
    int i = 0, j = 0, holdValue = 0;
    for( i = 0; i<array.length; i  ){
        for(j = 0; j<array.length; j  ){
            if(array[i]==array[i 1]){
                holdValue = array[i][j];
            }
        }
    }
    System.out.println(holdValue); //I tried calling in main but nothing prints out.
}

Edit: I tried -1 on while loop, as someone suggested. Still didn't print anything on the screen. I also forgot to mention that all data was read from an external file. I don't think that would make any difference whatsoever, but I think it's a good idea to inform the readers still. The assessment had more tasks, this was the only one that is stopping me from finishing this.

    public static void thirdValidation(int[][] array) {
   
    int i = 0;
    for (int[] elements : array) {
        while (i < array.length - 1) {
            while (i > 0) {
                if (elements[i] == elements[i - 1]) {
                    System.out.println(elements[i]);
                }
            }
        }
    }
}

CodePudding user response:

Basically, here is my set of data (I made them up for testing) that I am supposed to validate. For example, the second row has 35 (right next to each other) so I am supposed to print yes. Same goes for the fifth row, I am also supposed to print 'yes' because it has 51 twice. It's not supposed to print yes for the first row, although it has 23 twice

So you are saying that you are supposed to check each row and you also mention that you want a method that returns true/false.

This means that you want to have a method that only accepts a single row as a parameter, iterates over it, checks for the condition and returns true or false based on the result.

So the method signature would be something like this

/**
 * Checks if the row contains a repeating value at adjacent indices.
 *
 * @param row the row to check
 * @return <code>true</code> if the row contains a repeating value at adjacent indices,
 *         <code>false</code> otherwise
 */
public static boolean rowContainsAdjacentDuplicates(int[] row) {
    // TODO: implement the logic
    return false;
}

In the above method you would only be focusing on finding a duplicate adjacent value inside a normal one-dimensional array, as opposed to inside a 2D array. As you already suggested, iterating over the array and comparing the current and the previous (or the next) element value is a way to go. Either way, you have to make sure to not go out of bounds.

As far as returning true/false there are a few ways you could go about that

  1. return true as soon as you find adjacent duplicates and return false at the end of this method
  2. have a boolean variable starting as false and set it to true when you find adjacent duplicates and return the boolean variable at the end of this method

The approach #2 is wasteful, because it keeps iterating even after it already knows the result is true. However, approach #2 would be valid if you had to check (or count) all occurrences instead of just the first one. That's why I am mentioning it here.

Then the method that would be calling the above method, would be just iterating over the 2D array, making sure that the above method is called for each row in the array. It would also be checking the return value and based on it (true/false) it would decide whether to print the message or not.

So the method signature would be something like this

/**
 * Prints the row index? followed by "Yes" for each row containing
 * a repeating value at adjacent indices.
 *
 * @param array the array to validate
 */
public static void validate(int[][] array) {
    // TODO: iterate over the array and for each row
        // call rowContainsAdjacentDuplicates for the current row
        // if the returned value is true
            // print something that fits the documentation
        // else
            // just ignore for rows where false is returned?
}

I outlined the logic in the comments above, but the logic basically fits what you were already doing in your previous attempts. What is different now, is that the problem is split into 2 parts so it will be easier to reason about and it is less error prone, because you won't be using indices in the same scope across 3 for/while loops. This is the reason why your while attempt that tries to print "founded" is not working, because the index i is not reset for each row iteration. Reset that i to zero at the start of the for loop and voila!

If you run into difficulties implementing either of the above methods, let me know in the comments and I will gladly help.

Two things that can help going forward:

  1. When problem solving, try to split the problem into smaller parts that you can solve separately (sometimes even in isolation) then combine the solutions into the solution of your original problem
  2. if you are writing code inside an IDE, they have amazing support for step by step debugging. You place some breakpoints in your code and press Debug instead or Run. When the debugger stops at a breakpoint, you can step through the code and check values inside variables/arrays/classes etc. (you can step by step debug also if you are not using an IDE, but it is a bit trickier to set it up)

CodePudding user response:

I tried it, according to your idea, your definition of i may be wrong.

 public static void validation(int[][] array) {
   System.out.println();
   int i = 0;
   for (int[] element : array) {
    while (i < array.length) {
        //In this place, i will not become 0 to continue the recursion
        if (i > 0) {
            /**
             * Exit this loop when it is equal to 5, but you are defining a two- 
             * dimensional array,
             * and in the second loop, you must re-loop the second one- 
             *dimensional array with 0 as the index
             */
            if (element[i] == element[(i - 1)]) {
                System.out.println("founded");
            }
         }
        i  ;
      }
   }
}

You just need to change the defined position of i to print successfully.

public static void validation(int[][] array) {
    System.out.println();

    for (int[] element : array) {
        //i->position
        int i = 0;
        while (i < array.length) {
            if (i > 0) {
                if (element[i] == element[(i - 1)]) {
                    System.out.println("founded");
                }
            }
            i  ;
        }
    }
}

I don't know if my understanding is wrong, I hope this helps you. [the result][1] [1]: https://i.stack.imgur.com/LNziQ.png

CodePudding user response:

I broke down the problem into two different functions:

  1. analyzeMatrix
  2. findAdjacency

The first one is to iterate over each row and the second one is to iterate over each item on a single row.

What I assumed regarding the objective of the program that you mentioned at the top is that you need to verify for duplicate adjacent values, and then verify non-adjacent duplicate values. So for example the first row does not have adjacent duplicate values but it still matches non-adjacent duplicate values. Both cases would return true for the row I guessed.

If my assumption is correct, thinking carefully the adjacency of two numbers would be present in both cases, one sorted and the other not sorted. For example [23, 14, 42, 34, 23], that row originally does not have an adjacent duplicate value, but if you want to verify for duplicate numbers there is no any restriction to sort it, so, if you sort it, you get [14, 23, 23, 34, 42] and now you have an adjacency in the row.

Having said that, the following is the code I wrote to achieve the objective:

public static void main(String[] args)
{
    int[][] testData = new int[][]{
        {23, 14, 42, 34, 23},
        {35, 35, 42, 28, 38},
        {35, 34, 45, 46, 47},
        {40, 43, 35, 50, 49},
        {21, 33, 10, 51, 51} 
    };
    
    analyzeMatrix(testData);
}

public static void printResult(int[][] data, boolean[] result)
{
    int index = 0;
    for (int[] element: data)
    {
        System.out.format("Row %d: ", index);
        for(int item : element)
        {
            System.out.format("%d ", item);
        }
        
        String resultText = result[index  ] == true ? "YES": "NO";
        System.out.format("[%s]", resultText);
        System.out.println();
    }
}

public static void analyzeMatrix(int[][] data)
{
    boolean[] adjacencyResults = new boolean[data.length];
    boolean[] duplicateResults = new boolean[data.length];
    
    int adjacencyResultsIndex = 0;
    int duplicateResultsIndex = 0;
    
    for(int[] element : data)
    {
        adjacencyResults[adjacencyResultsIndex  ] = findAdjacency(element);
        /* Clone the row to keep original */
        int[] sortedElement = element.clone();
        /* Sort elements in the row */
        Arrays.sort(sortedElement);
        duplicateResults[duplicateResultsIndex  ] = findAdjacency(sortedElement);
    }
    
    System.out.println("Adjancecy analysis");
    printResult(data, adjacencyResults);
    System.out.println();
    System.out.println("Duplicates analysis");
    printResult(data, duplicateResults);
}

public static boolean findAdjacency(int[] element)
{
    boolean result = false;
    /* 
    nextItemIndex stores the index for the next item 
    that would be verified against the current item of the iteration.
    */
    int nexItemIndex = 0;
    /*
    elementLimit stores the limit for keeping the nextItemIndex count 
    controlled and avoid OutOfBoundExceptions.
    */
    int elementLimit = element.length - 1;
     
    for(int item : element){
        /*
        nextItemIndex is set based on a condition that verifies 
        if nextItemIndex is under the limit to continue counting up. 
        A false case would reset the nextItemIndex to 0 meaning that 
        the end of the row has been reached.
        */
        nexItemIndex = nexItemIndex < elementLimit ?   nexItemIndex : 0; 
        if (nexItemIndex != 0){
            int nextItem = element[nexItemIndex];
            if (item == nextItem)
            {
                result = true;
            }
        }
    }
    
    return result;
}

Result:

Adjancecy analysis
Row 0: 23 14 42 34 23 [NO]
Row 1: 35 35 42 28 38 [YES]
Row 2: 35 34 45 46 47 [NO]
Row 3: 40 43 35 50 49 [NO]
Row 4: 21 33 10 51 51 [YES]

Duplicate analysis
Row 0: 23 14 42 34 23 [YES]
Row 1: 35 35 42 28 38 [YES]
Row 2: 35 34 45 46 47 [NO]
Row 3: 40 43 35 50 49 [NO]
Row 4: 21 33 10 51 51 [YES]
  • Related