I'm currently working on a homework assignment and I'm really stuck on this idea of recursively searching an array without a row and column to index. I believe I can use helper methods but I'm new to recursion and find it a little confusing. This is the method that I'm not allowed to change (for the purpose of the assignment)
public Couple search(int[][]array, int element){
}
I'm also provided an inner class from the instructor. We haven't learned anything about inner classes, however, the appear to be nothing special. It is basic and I doesn't do anything special so I won't include the code unless there is something that is needed that I don't know. (I don't want to be cheating and I want to more-or-less figure it out too).
private class Couple{
// declaration of (int) row and (int) col
public Couple(row, col){
// this.row = row
// col = col
}
public String toString(){
// returns string
}
}
EDIT: I also can't use any loops
Edit: removed for-loop, added recursive Example
example for recursive subroutine
public class FindElement2DimArrayExample {
private class Couple {
private int row;
private int col;
public Couple(int row, int col) {
this.row = row;
this.col = col;
}
public String toString() {
return "[" + row + ", " + col + "]";
}
}
public static void main(String[] args) {
int[][] array = new int[][] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
System.out.println(new FindElement2DimArrayExample().search(array, 5));
}
public Couple search(int[][] array, int element) {
return searchRecursively(array, element, 0, 0);
}
public Couple searchRecursively(int[][] array, int element, int actualRow, int actualCol) {
if (array.length <= actualRow) {
return null;
} else if (array[actualRow].length <= actualCol) {
return searchRecursively(array, element, actualRow + 1, 0);
} else if (array[actualRow][actualCol] == element) {
return new Couple(actualRow, actualCol);
} else {
return searchRecursively(array, element, actualRow, actualCol + 1);
}
}
}
Recursion is not the best way to search a 2D Array, but if it is your assignment, you may try to realize it via the "Divide and Conquer" approach: Split the array into two parts and recursively call the method again on these two parts until you found the element.
Maybe this is useful for you: how to search elements in a 2d array using recursion
You didn't specify that you cant write some other method...
So i'd write another search method with signature:
private Couple search(Couple couple, int[][] array, int element)
Containing the following:
static private Couple search(Couple couple, int[][] array, int element) {
try {
System.out.println("Checking:" + couple + (array[couple.col][couple.row]));
} catch (ArrayIndexOutOfBoundsException aioobe) {}
if (couple.col>=array.length) return search(new Couple(0,couple.row+1),array,element);
if (couple.row>=array[0].length) return new Couple(-1,-1);
if (array[couple.row][couple.col] == element) return couple;
else return search(new Couple(couple.col+1,couple.row),array,element);
}
and call it from your other method by:
static public Couple search(int[][] array, int element) {
return search(new Couple(0,0),array,element);
}
That should do the trick.
Other then that (if you cant write additional method) then I'd use a stack.
full code:
public class NewClass1 {
static class Couple {
int col, row;
public Couple(int col, int row) {
this.col = col;
this.row = row;
}
#Override
public String toString() {
return "Couple{" + "col=" + col + ", row=" + row + '}';
}
}
static int[][] getArr(int nx, int ny) {
Random rand = new Random();
int[][] arr = new int[nx][ny];
for (int i = 0; i < nx; i++) {
for (int j = 0; j < ny; j++) {
arr[i][j] = rand.nextInt(90)+10;
}
}
return arr;
}
static void print(int [][] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + ";");
}
System.out.println("");
}
}
static public Couple search(int[][] array, int element) {
return search(new Couple(0,0),array,element);
}
static private Couple search(Couple couple, int[][] array, int element) {
try {
System.out.println("Checking:" + couple + (array[couple.col][couple.row]));
} catch (ArrayIndexOutOfBoundsException aioobe) {}
if (couple.col>=array.length) return search(new Couple(0,couple.row+1),array,element);
if (couple.row>=array[0].length) return new Couple(-1,-1);
if (array[couple.row][couple.col] == element) return couple;
else return search(new Couple(couple.col+1,couple.row),array,element);
}
public static void main(String[] args) {
int[][] arr = getArr(10,10);
print(arr);
System.out.println(search(arr,11));
}
}
Related
I am using an ArrayList to store objects that are "valid" for the purposes of my program and referencing it later in the same class file.
private static ArrayList<TownResource> validResources = new ArrayList<>();
A public method is called, which then calls a private method within the class that makes validResources's size nonzero.
public static boolean detection(int row, int col, TownResource[][] rArray, ResourceEnum[][][] bT, BuildingEnum buildingType) {
int checkTime = 0;
int patternIndex = 0;
try {
for (int i = 1; i < checkTime+1; i++) {
if (compare(row, col, rArray, buildingTemplate[patternIndex], buildingType)) {
for (int j = 0; j < validResources.size(); j++) {
validResources.get(j).setScannedBuilding(buildingType);
}
System.out.println("Size at compare" + validResources.size());
return true;
}
}
}
catch (ArrayIndexOutOfBoundsException e){
//System.out.println("Out of bounds exception?");
}
return false;
}
The compare method is a private method that on one condition, may clear validResources.
private static boolean compare(int row, int col, TownResource[][] rArray, ResourceEnum[][] buildingTemplate, BuildingEnum buildingType) {
for (int r = 0; r < buildingTemplate.length; r++) {
for (int c = 0; c < buildingTemplate[r].length; c++) {
if (match(rArray[row+r][col+c], buildingTemplate[r][c])) {
//System.out.println("Successful comparison at " + (row+r) + ", " + (col+c));
}
else {
validResources.clear();
return false;
}
}
}
return true;
}
match is what sets validResources to be nonzero in size:
private static boolean match(TownResource toBeChecked, ResourceEnum checker) {
if (checker == ResourceEnum.NONE) {
return true;
}
else if (toBeChecked.getResource() == checker) {
validResources.add(toBeChecked);
return true;
}
return false;
}
However, when I know validResources to be nonzero in size(this causes detection to return true which triggers a new method placement), it becomes zero.
public static void placement(TownResource[][] rArray, Building[][] bArray, BuildingEnum building) {
// other parts of method commented out for example
System.out.println(validResources.size());
for (int i = 0; i < validResources.size(); i++) {
System.out.println("Is this statement firing?");
System.out.println(validResources.get(i).getResource());
validResources.get(i).setResource(ResourceEnum.NONE);
}
Have I declared validResources incorrectly? Or is there something else at play?
Thank you.
This was an error in how I executed detection(). This method is called by another method within another class when iterating through a 2D array. The ArrayList validResources becomes nonempty in one check, but gets overwritten by another as a result of the program not calling placement until every object in the 2D array had detection called on it. I changed this to call placement immediately.
Good evening everyone, sorry for bothering.
I have a problem while trying to configure the "DynamicArray" by myself. Here I made a sort method but the terminal shows "error:unexpected type", I actually have some difficulty of solving this, can some one help me to check what's the problem I have?
Thanks in advance.
Here is my code:
package lab2;
public class DynamicArray {
private static int INITIAL_CAPACITY = 5;
private int[] data;
private int size;
public DynamicArray() {
data = new int[INITIAL_CAPACITY];
size = 0;
}
// Returns `true` if the array is empty.
public boolean isEmpty() {
if (size==0){
return true;
}
else{
return false;
}
}
// Returns the size of the array.
public int size() {
return size;
}
// Remove all elements from data.
public void clear() {
size=0;
}
// Create a `String` with the elements of the array separated by comma, without a new line character at the end.
// For instance: 4, 5, 6
public String toString() {
if(size==0){
return "";
}
StringBuilder a = new StringBuilder();
for(int i=0;i<size;i++){
if(i==size-1){
a.append(data[i]);
}
else{
a.append(data[i]).append(",").append(" ");
}
}
return a.toString();
}
// Returns `true` if the array `data` is full: no more element can be added to `data`.
// Returns `false` otherwise.
private boolean isFull() {
if(size==data.length){
return true;
}
return false;
}
// If the array `data` is full:
// 1. Create a new array `data2` doubling the size of data.
// 2. Copy the elements of `data` into `data2`.
// 3. Assign `data2` to `data`.
private void realloc() {
if(size==data.length){
int [] data2 = new int[data.length*2];
System.arraycopy(data, 0, data2, 0,data.length);
data=data2;
}
}
// The element `x` is added to `data`, and `size` is incremented by one.
// `data` is automatically resized if it is too small.
public void add(int x) {
realloc();
data[size++]=x;
}
private void checkIndex(int idx) {
if(idx >= size) {
throw new ArrayIndexOutOfBoundsException();
}
}
// Set the ith element of `data` to `x`.
public void set(int idx, int x) {
int a = data[idx];
data[idx]=x;
}
// Return the element at the index `idx` of `data`.
public int get(int idx) {
checkIndex(idx);
return data[idx];
}
// Remove the element at index `idx`.
// Shift all the elements after `idx` of one position to the left.
public void remove(int idx) {
checkIndex(idx);
for(int i = idx; i<size-1; i++){
data[i]=data[i+1];
}
size--;
}
}
And the code which the problem appear:
package lab2;
public class DynamicArrayTest {
public static void main(String[] args) {
DynamicArray array = new DynamicArray();
testAdd(array);
testRemove(array);
testGet(array);
testRealloc(array);
testSort(array);
}
public static void testAdd(DynamicArray array) {
System.out.println("Test add method.");
System.out.println(array.size());
System.out.println(array.isEmpty());
array.clear();
System.out.println(array.size());
System.out.println(array.isEmpty());
array.add(4);
array.add(5);
array.add(6);
System.out.println(array);
}
public static void testRemove(DynamicArray array) {
System.out.println("Test remove method.");
try {
for(int i = 0; i < 3; ++i) {
array.remove(1);
System.out.println(array);
System.out.println(array.size());
System.out.println(array.isEmpty());
}
}
catch(ArrayIndexOutOfBoundsException e) {}
array.remove(0);
System.out.println(array);
System.out.println(array.size());
System.out.println(array.isEmpty());
}
public static void testGet(DynamicArray array) {
System.out.println("Test get method.");
try {
array.get(4);
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("OK");
}
}
public static void testRealloc(DynamicArray array) {
System.out.println("Test realloc method.");
for(int i = 0; i < 100; ++i) {
array.add(i);
}
System.out.println(array);
while(!array.isEmpty()) {
array.remove(0);
}
System.out.println(array);
System.out.println(array.size());
System.out.println(array.isEmpty());
}
public static void testSort(DynamicArray array){
System.out.println("Sort the array.");
for(int i =0; i<array.size(); ++i){
for (int j=0; j<array.size() - i; ++j){
if (array.get(j-1)<array.get(j)){
int a = array.get(j-1);
array.get(j-1)=array.get(j);
array.get(j)=a;
}
}
}
}
}
And the error code:
public static void testSort(DynamicArray array){
System.out.println("Sort the array.");
for(int i =0; i<array.size(); ++i){
for (int j=0; j<array.size() - i; ++j){
if (array.get(j-1)<array.get(j)){
int a = array.get(j-1);
array.get(j-1)=array.get(j);
array.get(j)=a;
}
}
}
}
Again, the terminal shows:
src/lab2/DynamicArrayTest.java:72: error: unexpected type
array.get(j-1)=array.get(j);
^
required: variable
found: value
src/lab2/DynamicArrayTest.java:73: error: unexpected type
array.get(j)=a;
^
required: variable
found: value
2 errors
Thanks a lot for your help.
array.get(j-1)=array.get(j);
array.get(j)=a;
should be
array.set(j-1, array.get(j));
array.set(j, a);
This line is trying to assign a value to a value. The left side of this statement would need to be a variable. You did the same mistake in multiple places.
array.get(j-1)=array.get(j);
You either need to assign the value of array.get(j) to a variable or call a setter on the array object, setting the position of j-1 to the value returned by array.get(j). Depending on what you want to do with the value.
public class ArrayMethodsTest
{
public static void main(String[] args)
{
int[] tester = {0,1,2,3,4,5};
ArrayMethods test = new ArrayMethods(tester);
for(int element : test)
{
System.out.print(element + " ");
}
test.shiftRight();
for(int element : test) //error: for-each not applicable to expression type
{
System.out.print(element + " ");
}
}
}
I figure what the problem is. Thanks to jigar joshi. However I still need to use the ArrayMethods methods for the tester that I created. I know that they work but how can it be possible to provide a tester class for an object that isn't an array since the methods are for arrays.
public class ArrayMethods
{
public int[] values;
public ArrayMethods(int[] initialValues)
{
values = initialValues;
}
public void swapFirstAndLast()
{
int first = values[0];
values[0] = values[values.length-1];
values[values.length-1] = first;
}
public void shiftRight()
{
int first = 0;
int second = first;
for(int i =0; i < values.length; i++)
{
if(i < values.length-1)
{
first = values[i];
second = values[i+1];
values[i+ 1] = first;
}
if(i == values.length)
{
values[i] = values[0];
}
}
}
}
//0,1,2,3,4,5
//5,0,1,2,3,4
test is reference of ArrayMethods which is not an Iterable or an array type and so is the error
You've already encountered the issue in which you can't iterate over an ArrayMethods, since it's not iterable. What it seems like you want to do is iterate over its values instead, considering that values is a public field.
for(int element : test.values) {
System.out.print(element + " ");
}
I'm attempting to add elements into an arraylist (also append an arraylist to the other), however it seems to rewrite everything else already present in that arraylist too - so I'm left with an arraylist filled with the last element added.
Here's the method concerned:
private static ArrayList<Move> checkX(int r, int c) {
ArrayList<Move> moves = new ArrayList<Move>();
if (jumps()) { // if jumps are found && this piece can jump
for (int i = 0; i <= 1; i+=2) {
if (Character.isLowerCase(board[r-1][c+i]) && board[r-2][c+2*i] == ' ') {
}
}
} else { // if no jumps are found then move normally
for (int i = -1; i <= 1; i+=2) {
try {
if (board[r-1][c+i] == ' ') {
Move tempMove = new Move(r, c);
tempMove.addDestination((r-1), (c+i));
moves.add(tempMove);
}
} catch (Exception e) {}
}
}
for (int i = 0; i < moves.size(); i++) {
System.out.println(moves.get(i).toString());
}
return moves;
}
Move class:
public class Move {
private static ArrayList<int[]> destinations;
// private static char[][] tmpboard;
public Move(int r, int c) {
destinations = new ArrayList<int[]>();
int[] initSquare = {r, c};
destinations.add(initSquare);
}
public void addDestination(int r, int c) {
int[] destinationSquare = {r, c};
destinations.add(destinationSquare);
}
public ArrayList<int[]> getMove() {
return destinations;
}
public String toString() {
String returnStr = "";
for (int i = 0; i < destinations.size(); i++) {
returnStr += Arrays.toString(destinations.get(i));
}
return returnStr;
}
}
Every time I attempt to print out everything stored in an instance of 'moves' it seems to only print out the last element added to the list n times.
private static ArrayList<int[]> destinations;
Here's your issue. Try removing the static modifier.
What static here means that the latest additions of destinations will affect all Move instances, which makes them identical.
It's possible you were thinking of final there instead, which would make more sense.
public int search(String type) {
for (int i = 0; i < size; i++) {
if (array[size-1-i].contains(type)) return i;
}
return -1;
}
I am having trouble doing a recursive function of this previous search function , can somebody help me ?
For a recursive function, a simple solution would be to pass in the value you want to search and the index to search at as parameters to the function.
Then you check
if the index passed in is greater than length of array , then return -1 (since we were not able to find the element.
if you can find the value pass in at the index passed in, if yes, just return that index ,
if not above 2 , then try to search it at next index.
For this recursive function, start at index 0 , by passing 0 when calling the function.
Example code -
public int search(String type, int index) {
if (index >= array.length) {
return -1;
}
else if(array[index].contains(type)) {
return array.length - i + 1; # assuming size from your function is array.length
}
else {
return search(type, index + 1)
}
}
It seems you want to write a recursive variant of this search function. I am not doing any optimization in your code as you need to take care of that. I have assumed few things to make your code compile and here is the code I have tried:
static String[] array = new String[] {"John", "Sam", "David"};
static int size = array.length;
public static void main(String[] args) {
int index = searchRecursive(0,"Sam");
System.out.println("Index: " + index);
}
public static int searchRecursive(int indexToCheck, String type) {
int result = -1;
if(indexToCheck<size) {
if(array[size-1-indexToCheck].contains(type)) {
result = indexToCheck;
} else {
result = searchRecursive(indexToCheck+1,type);
}
}
return result;
}
public static int searchIterative(String type) {
for (int i = 0; i < size; i++) {
if (array[size-1-i].contains(type)) return i;
}
return -1;
}