how to use recursion for nested 'for' loops - java

I have a problem with nested for loops in java. My problem is that at the beginning I don't know exactly how many for loops I will need. It is set somewhere in the middle of my program. So let say my program creates an array. If the array has 3 elements then I create a three for loops like below.
for(int i = 0; i<tab[0].length() ; i++){
for(int j = 0; j<tab[1].length() ; j++){
for(int k = 0; k<tab[2].length() ; k++){
System.out.println(i+" "+j+" "+k);
}
}
}
If my program created an array with 4 elements then it would be like this:
for(int i = 0; i<tab[0].length() ; i++){
for(int j = 0; j<tab[1].length() ; j++){
for(int k = 0; k<tab[2].length() ; k++){
for(int h = 0; h<tab[3].length() ; h++){
System.out.println(i+" "+j+" "+k+" "+h);
}
}
}
}
Can any one tell me how to do this with recursion? I can have 2 nested loops but I can have 10 of them and always at the end I would like to print in the console numbers associated with all loops (i,j,k,h)

Here is a solution. At each recursive call, previousTabs becomes 1 longer and tabs becomes 1 shorter.
public static void iterate(int[] previousValues, int[] tabs) {
if (tabs.length == 0) {
System.out.println(Arrays.toString(previousValues));
}
else {
final int[] values = new int[previousValues.length + 1];
for (int i = 0; i < previousValues.length; i++) {
values[i] = previousValues[i];
}
final int[] nextTabs = new int[tabs.length - 1];
for (int i = 0; i < nextTabs.length; i++) {
nextTabs[i] = tabs[i + 1];
}
for (int i = 0; i < tabs[0]; i++) {
values[values.length - 1] = i;
iterate(values, nextTabs);
}
}
}
public static void iterate(int[] tabs) {
iterate(new int[0], tabs);
}

Related

when filling a 2d array it gets null values

Im trying to initialise all the elements of the 2d array into a string "EMPTY". but When ever I try to initialise the array it gets null values. I checked errors in the for loop but couldn't see any
public static void arr_2d(){
String [][] arr = new String[3][2];
for (int i = 0; i < arr.length; i++) {
for (int a = 0; a < arr[i].length; a++) {
arr[i][a] = "EMPTY";
}
for (int b = 0; b < arr.length; b++) {
for (int j = 0; j < arr[b].length; j++) {
System.out.print(arr[b][j] + " ");
}
System.out.println();
}
}
}
Your loops are nested wrongly, which will result in the filling process not being complete while you're trying to process its results. You need
public static void arr_2d() {
String[][] arr = new String[3][2];
for (int i = 0; i < arr.length; i++) {
for (int a = 0; a < arr[i].length; a++) {
arr[i][a] = "EMPTY";
}
}
for (int b = 0; b < arr.length; b++) {
for (int j = 0; j < arr[b].length; j++) {
System.out.print(arr[b][j] + " ");
}
System.out.println();
}
}
Actually for(int b) is in for(int i); that's why you observe null values. If you move for(int b) outside of for(int i), there will be no null values.
public static void arr_2d(){
String [][] arr = new String[3][2];
for (int i = 0; i < arr.length; i++) {
for (int a = 0; a < arr[i].length; a++) {
arr[i][a] = "EMPTY";
}
}
for (int b = 0; b < arr.length; b++) {
for (int j = 0; j < arr[b].length; j++) {
System.out.print(arr[b][j] + " ");
}
System.out.println();
}
}
Check the comments given below in the snippet:
public static void arr_2d(){
String [][] arr = new String[3][2];
for (int i = 0; i < arr.length; i++) {
for (int a = 0; a < arr[i].length; a++) {
arr[i][a] = "EMPTY";
// you can have the sysout statement here as well instead of having looping the entire array again.
System.out.print(arr[i][a] + " ");
}
// this loop must be executed separately inorder to check values present in the array or else you can have a sysout statement when assigning the "empty" value in the array.
for (int b = 0; b < arr.length; b++) {
for (int j = 0; j < arr[b].length; j++) {
System.out.print(arr[b][j] + " ");
}
System.out.println();
}
}
}
Although the answers you have are correct I will add that one problem is your code style is prone to errors.
Your mistake was traversing the array incorrectly. The correct way is traversing the array twice, one of filling and another for printing, but instead it seems you have attempted to do everything in one shot. That mistake can be avoided with a better code style.
This is how I would have written your code in imperative style:
String[][] arr = new String[3][2];
for (String[] a : arr)
Arrays.fill(a, "EMPTY");
for (String[] a : arr)
System.out.println(Arrays.toString(a));
Notice the code is much shorter, so there's less chances of mistakes. It's also a lot more obvious that you're traversing twice.
Instead of traversing an array explicitly:
for (int i = 0; i++; i < arr.length())
Use the implicit for loop:
for (String[] value: arr)
Instead of filling an array explicitly:
for (int a = 0; a < arr[i].length; a++) {
arr[i][a] = "EMPTY";
}
Use the already provided fill method:
Arrays.fill(value, "EMPTY");
Instead of printing an array explicitly:
for (String string : strings) {
System.out.print(string + " ");
}
System.out.println();
Use the already provided print method:
for (String[] a : arr)
System.out.println(Arrays.toString(a));
However, I would have written in functional style:
String [][] arr = new String[3][2];
Arrays.stream(arr)
.forEach(a -> Arrays.fill(a, "EMPTY"));
Arrays.stream(arr)
.map(Arrays::toString)
.forEach(System.out::println);
One particular advantage is that you are encouraged to think in a more abstract way. Instead of thinking how to explicitly set or print each element of the array, you are encouraged to use methods that implicitly traverse, transform or perform generic computations on all elements of the array.

Least Common Subsequence with optimized space (two columns, since it's Markovian)

I'm trying to write LCS of two String objects using bottom-up dynamic programming. I'm able to get it to work properly with O(mn) space. However, as I could see, I don't need all the previous columns. So, I tried to modify it to get it fit in 2 columns so space become O(m). However, it's not working for all inputs (for example, to this: abcabc and abcbcca). What am I missing here? NOT HW, NOT CONTEST nothing. Practicing DP.
public int longestCommonSubsequence(String input) {
char[] firstStr = this.string.toCharArray();
char[] secondStr = input.toCharArray();
int[][] maxLength = new int[firstStr.length+1][2];
for(int i=0; i <= firstStr.length; i++) {
maxLength[i][0] = 0;
}
for(int j=0; j < 2; j++) {
maxLength[0][j] = 0;
}
for(int i=0; i < firstStr.length; i++) {
for(int j=0; j < secondStr.length; j++) {
if(firstStr[i] == secondStr[j]) {
maxLength[i+1][1] = 1 + maxLength[i][0];
}
else {
maxLength[i+1][1] = maxLength[i][1]>maxLength[i+1][0]?maxLength[i][1]:maxLength[i+1][0];
}
}
//Copy second row to first row
for(int l =0; l < firstStr.length; l++) {
maxLength[l][0] = maxLength[l][1];
}
}
return maxLength[firstStr.length -1][0];
}
This has two problems:
if(firstStr[i] == secondStr[j]) {
maxLength[i+1][1] = 1 + maxLength[i][0];
// check here if maxLength[i+1][1] is greather than the last max length
}
else {
maxLength[i+1][1] = maxLength[i][1]>maxLength[i+1][0]?maxLength[i][1]:maxLength[i+1][0];
// absolutely wrong: maxLength[i+1][1] = 0;
}
Here can see the algorithm with micro optimization.
public static int lcs(String s0, String s1) {
int maxLength = 0;
int [][]lengths = new int[2][s1.length()+1];
for (int i = 0; i < s0.length(); i++) {
for (int j = 0; j < s1.length(); j++) {
if (s0.charAt(i) == s1.charAt(j)) {
lengths[0][j+1] = lengths[1][j] + 1;
if (lengths[0][j+1] > maxLength) {
maxLength = lengths[0][j+1];
}
} else {
lengths[0][j+1] = 0;
}
}
int []temp = lengths[0];
lengths[0] = lengths[1];
lengths[1] = temp;
}
return maxLength;
}

Java exercise - display table with 2d array

I'm struggling to finish a java exercise, it involves using 2d arrays to dynamically create and display a table based on a command line parameter.
Example:
java table 5
+-+-+-+-+-+
|1|2|3|4|5|
+-+-+-+-+-+
|2|3|4|5|1|
+-+-+-+-+-+
|3|4|5|1|2|
+-+-+-+-+-+
|4|5|1|2|3|
+-+-+-+-+-+
|5|1|2|3|4|
+-+-+-+-+-+
What i have done so far:
public static void main(String[] args) {
int num = Integer.parseInt(args[0]);
String[][] table = new String[num*2+1][num];
int[] numbers = new int[num];
int temp = 0;
for(int i=0; i<numbers.length; i++)
numbers[i] = i+1;
// wrong
for(int i=0; i<table.length; i++){
for(int j=0; j<num;j++){
if(i%2!=0){
temp=numbers[0];
for(int k=1; k<numbers.length; k++){
numbers[k-1]=numbers[k];
}
numbers[numbers.length-1]=temp;
for(int l=0; l<numbers.length; l++){
table[i][j] = "|"+numbers[l];
}
}
else
table[i][j] = "+-";
}
}
for(int i=0; i<table.length; i++){
for(int j=0; j<num; j++)
System.out.print(table[i][j]);
if(i%2==0)
System.out.print("+");
else
System.out.print("|");
System.out.println();}
}
This doesn't work, since it prints 1|2|3|4 in every row, which isn't what I need. I found the issue, and it's because the first for loop changes the array order more times than needed and basically it returns as it was at the beginning.
I know that probably there's a way to achieve this by writing more code, but I always tend to nest as much as possible to "optimize" the code while I write it, so that's why I tried solving this exercise by using less variables and loops as possible.
You are too complex. Hard to find your error. Straight code follows:
public static void main(String[] args) {
//int num = Integer.parseInt(args[0]);
int num = 5; // for test
// creating 2d array
int[][] figures = new int[num][num];
// filling the array
for(int row=0; row<figures.length; ++row) {
for(int col=0; col<figures[row].length; ++col) {
figures[row][col] = (row + col) % num + 1;
}
}
// printing the array
for(int row=0; row<figures.length; ++row) {
// printing border
for(int col=0; col<figures[row].length; ++col) {
System.out.print("+-");
}
System.out.println("+");
// printing data row
System.out.print("|");
for(int col=0; col<figures[row].length; ++col) {
System.out.print(figures[row][col]);
System.out.print("|");
}
System.out.println();
}
// printing final border
for(int col=0; col<figures[0].length; ++col) {
System.out.print("+-");
}
System.out.println("+");
}
public static void main(String args[]){
int dimension = Integer.valueOf(args[0]);
int[][] twoDimArray = new int[dimension][dimension];
for(int i=0;i<dimension;i++){
for(int j=0;j<dimension;j++){
System.out.print("|"+((i+1)%(dimension+1)));
} //end of j loop
} //end of i loop
} //end of main
The above is only the logic for printing the numbers in the specified sequence.
The other design pattern ( +-+ ) thing i guess u can manage.
the following codes will initialize a 2d int array for the data (1-5 in your example). and print the table. note that the table structure was not save in a String 2d-array. just print the table out. see comments in line.
public static void main(String[] args){
final int num = 5; //hardcoded 5, just for testing.
final int[][] data = new int[num][num];
for (int r = 0; r < data.length; r++) {
for (int c = 0; c < data[r].length; c++) {
final int t = r + c + 1;
data[r][c] = t <= num ? t : t - num;
}
}
// now we have all int data in data 2D-array
// here is the +-+- line
final StringBuilder sb = new StringBuilder("+");
for (int i = 0; i < data.length; i++)
sb.append("-+");
// now print the table
for (int r = 0; r < data.length; r++) {
System.out.println(sb.toString());
for (int c = 0; c < data.length; c++)
System.out.print("|" + data[r][c]);
System.out.println("|");
}
System.out.println(sb.toString());
}
output:
if you give num=9 as argument. the codes above will print:
+-+-+-+-+-+-+-+-+-+
|1|2|3|4|5|6|7|8|9|
+-+-+-+-+-+-+-+-+-+
|2|3|4|5|6|7|8|9|1|
+-+-+-+-+-+-+-+-+-+
|3|4|5|6|7|8|9|1|2|
+-+-+-+-+-+-+-+-+-+
|4|5|6|7|8|9|1|2|3|
+-+-+-+-+-+-+-+-+-+
|5|6|7|8|9|1|2|3|4|
+-+-+-+-+-+-+-+-+-+
|6|7|8|9|1|2|3|4|5|
+-+-+-+-+-+-+-+-+-+
|7|8|9|1|2|3|4|5|6|
+-+-+-+-+-+-+-+-+-+
|8|9|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+-+
|9|1|2|3|4|5|6|7|8|
+-+-+-+-+-+-+-+-+-+
you have make it more complicated try this Simple code :
enter code here
public static void main(String[] args)
{
int n = 5 ;
for(int i = 1 ; i <= n ;i++)
{
for(int l = 0 ; l < n;l++)
System.out.print("+-");
System.out.print("\n|");
for(int j = i ; j <=n;j++ )
{
System.out.print(j+"|");
}
for(int k = 1 ; i >= 2 && k <=i-1;k++)
{
System.out.print(k+"|");
}
System.out.println();
}
}

Java: Combination of recursive loops which has different FOR loop inside; Output: FOR loops indexes

currently recursion is fresh & difficult topic for me, however I need to use it in one of my algorithms.
Here is the challenge:
I need a method where I specify number of recursions (number of nested FOR loops) and number of iterations for each FOR loop. The result should show me, something simmilar to counter, however each column of counter is limited to specific number.
ArrayList<Integer> specs= new ArrayList<Integer>();
specs.add(5); //for(int i=0 to 5; i++)
specs.add(7);
specs.add(9);
specs.add(2);
specs.add(8);
specs.add(9);
public void recursion(ArrayList<Integer> specs){
//number of nested loops will be equal to: specs.size();
//each item in specs, specifies the For loop max count e.g:
//First outside loop will be: for(int i=0; i< specs.get(0); i++)
//Second loop inside will be: for(int i=0; i< specs.get(1); i++)
//...
}
The the results will be similar to outputs of this manual, nested loop:
int[] i;
i = new int[7];
for( i[6]=0; i[6]<5; i[6]++){
for( i[5]=0; i[5]<7; i[5]++){
for(i[4] =0; i[4]<9; i[4]++){
for(i[3] =0; i[3]<2; i[3]++){
for(i[2] =0; i[2]<8; i[2]++){
for(i[1] =0; i[1]<9; i[1]++){
//...
System.out.println(i[1]+" "+i[2]+" "+i[3]+" "+i[4]+" "+i[5]+" "+i[6]);
}
}
}
}
}
}
I already, killed 3 days on this, and still no results, was searching it in internet, however the examples are too different. Therefore, posting the programming question in internet first time in my life. Thank you in advance, you are free to change the code efficiency, I just need the same results.
// ...
recursion (specs, specs.size () - 1);
// ...
public void recursion(ArrayList<Integer> specs, int startWith){
for (int i = 0; i < specs.get(startWith); i++) {
// ...
if (startWith - 1 >= 0)
recursion (specs, startWith - 1);
}
}
Your function also need to now the index of the specs array to use for iteration, and also the previous numbers that should be printed:
public void recursion(ArrayList<Integer> specs, int index, String output) {
if( index >= specs.size() ) {
System.out.println(output);
return;
}
for (int i = 0; i < specs.get(index); i++ )
recursion( specs, index+1, Integer.toString(i) + " " + output );
}
The you should call it like this:
ArrayList<Integer> specs= new ArrayList<Integer>();
specs.add(5);
specs.add(7);
specs.add(9);
specs.add(2);
specs.add(8);
specs.add(9);
recursion( specs, 0, "" );
Does this snippet give the output you want? (It is compileable and executeable)
import java.util.ArrayList;
import java.util.List;
public class SO {
static ArrayList<Integer> specs = new ArrayList<Integer>();
static int[] i;
public static void main(String[] args) throws Exception {
specs.add(5); //for(int i=0 to 5; i++)
specs.add(7);
specs.add(9);
specs.add(2);
specs.add(8);
specs.add(9);
i = new int[specs.size()];
printMe(0, specs, i);
}
static void printMe(int depth, List<Integer> _specs, int[] i) {
if (_specs.isEmpty()) {
System.out.println(printI(i));
return;
} else {
for (int j = 0; j < _specs.get(0); j++) {
i[depth] = j + 1; // + 1 since you seems to want to go from 1 and not 0
printMe(depth + 1, _specs.subList(1, _specs.size()), i);
}
}
}
static String printI(int[] i) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < i.length; j++) {
sb.append(i[j]);
if (j < i.length - 1) {
sb.append(" ");
}
}
return sb.toString();
}
}
You can try this :
public static void loops(ArrayList<Integer> specs, int idx, StringBuilder res){
if(idx==specs.size()-1){
for (int i = 0; i < specs.get(idx); i++) {
System.out.println(i+" "+res);
}
}
else{
for(int i=0;i<specs.get(idx);i++){
res.insert(0,i+" ");
loops(specs,idx+1,res);
res.delete(0, 2);
}
}
}
And call with :
ArrayList<Integer> specs= new ArrayList<Integer>();
specs.add(5); //for(int i=0 to 5; i++)
specs.add(7);
specs.add(9);
specs.add(2);
specs.add(8);
specs.add(9);
loops(specs,0, new StringBuilder());

size of Two-dimensional arrays in Java

I want to make a loop on Two-dimensional array in Java.
How I do that? I wrote:
for (int i = 0; i<=albums.size() - 1; i++){
for (int j = 0; j<=albums.size() - 1; j++){
But it didn't work. Thanks.
Arrays have a read-only field called length, not a method called size. A corrected loop looks like this:
for(int i = 0; i < albums.length; i++ ) {
for (int j = 0; j < albums[i].length; j++) {
element = albums[i][j];
You have to recognize that a 2-D array is just an array whose element type happens to be another array. So the i loop iterates over each element in albums (which is an array) and the j loop iterates over that child array (with a potentially different size).
A more transparent way would be like this:
String[][] albums;
for(int i = 0; i < albums.length; i++ ) {
String[] childArrayAtI = albums[i];
for (int j = 0; j < childArrayAtI.length; j++) {
String element = childArrayAtI[j];
}
}
Try this if you are working with Java 1.5+:
for(int [] album : albums) {
for(int albumNo : album) {
System.out.print(albumNo + ", ");
}
System.out.println();
}
First of all, a two-dimensional array looks like this in Java:
int[][] albums = new int[10][10];
Now, for iterating over it:
for (int i = 0; i < albums.length; i++) {
for (int j = 0; j < albums[i].length; j++) {
int value = albums[i][j];
}
}

Categories

Resources