Add Elements of a 2-Dimensional Array using recursion - java

Hey guys I am having problems writing this part of my code. I have to sum up the elements of this 2-dimensional array using recursion. I understand what I need to do but I am not understanding how to implement this to step through the array. I keep receiving errors. Could someone please help me out?
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int[][] a;
a = new int[3][4];
int sum = 0;
System.out.println("Enter 12 numbers: ");
Scanner scan = new Scanner(System.in);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
a[i][j] = scan.nextInt();
}
}
sum = sum2D(a, 0, 0);
System.out.println("The sum of the array: " + sum);
}
public static int sum2D(int a[][], int row, int col) {
if (row == a.length-1) {
return a[row][col];
}
if (col == a[row].length-1) {
return a[row][col] + sum2D(a, row++, 0);
}
return a[row][col] + sum2D(a, row, col++);
}
}

The basic plan, when you need a recursive solution, is to look for a way to break down the problem so that it contains a smaller problem (or more than one smaller problem) that looks just like the original problem, only smaller.
For a 2-D array, this can be tricky. Say your array looks like
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
One's first thought might be to write a recursive function that takes a row and column, and adds a[row][column] to the sum of the rest of the array. The problem is that if, for example, row=0 and column=0, the "smaller problem" you have to solve looks like
+---------------------+
1 | 2 3 4 5 |
+---+ |
| 6 7 8 9 10 |
| 11 12 13 14 15 |
+-------------------------+
(please excuse the bad ASCII art). So now your smaller problem doesn't look like an array at all, but some weird polygon. It's still possible to use this approach, by writing a recursive function like
int sumOfWeirdShapedSectionOfArray(int[][] array, int firstRow, int firstCol)
But that's definitely an abuse of recursion. Better would be to break down the array into the "first row" and "the rest of the rows":
1 2 3 4 5
+-------------------------+
| 6 7 8 9 10 |
| 11 12 13 14 15 |
+-------------------------+
(Or you could break it into "the last row" and "the rest of the rows".)
Now, your smaller problem looks a lot like the original problem, right? So your answer would be that "the sum of the elements in the array is the sum of the first row, plus the sum of the elements in the smaller array starting with the next row". The second part of this is a recursive call. The first part, the sum of the first row, would require that you call a new function to add up a row; and since you're still not allowed to use loops, the "add up a row" function would also be recursive, but that should be easy.
Having said all this, nobody would ever use recursion in the real world on this problem. However, if the point is to get familiar with recursion so that you can use it when it's called for, then this sort of thought process is what you need to follow.

To do it without recursion, just have two nested for loops:
int sum = 0;
for(int i=0;i<array.length;i++)
for(int j=0;j<array[i].length;j++)
sum += array[i][j];
return sum;
To do it with recursion:
int sum2D(int a[][], int row, int col) {
if (row == a.length-1)
return a[row][col];
if(col == a[row].length-1)
return a[row][col]+sum2D(a,row+1,0);
return a[row][col]+sum2D(a,row,col+1);
}
Basically you're doing the same thing: going through each row and column and adding it together.
However, note that ther is a limit on how many recursive routines you can use. If you recurse too deep, you'll get a StackOverflow error.

The base condition was wrong in the above code:
Here is the code that works:
public static int addMatrix(int a[][],int r,int c){
if(r==a.length-1 && c==a[r].length-1)
return a[r][c];
if(c==a[r].length-1)
return a[r][c]+addMatrix(a,r+1,0);
return a[r][c]+addMatrix(a,r,c+1);
}

Equivalent "C" program here, but for number of Rows 4 and Number of columns 1 , I get unpredictable result why?
#include <stdio.h>
#include <string.h>
#include <conio.h>
int row,col;
main()
{
int a[][];
int nrow,ncols,summ = 0;
printf("Enter No of Rows:");
scanf("%d",&nrow);
printf("Enter No of Columns:");
scanf("%d",&ncols);
int arraylength,rowlength;
printf("Enter %d numbers: \n",nrow*ncols);
for (int i = 0; i < nrow; i++) {
for (int j = 0; j < ncols; j++) {
scanf("%d",&a[i][j]);
}
}
arraylength=sizeof(a)/sizeof(int);
summ = sum(a,0, 0,nrow,ncols);
printf("\n The sum of the array: %d ",summ);
getch();
}
int sum( int a[row][col],int row,int col,int RowLen,int ColLen)
{
if ((row == RowLen-1) && (col==(ColLen)-1)) {
return a[row][col];
}
if (col == (ColLen)-1)
{
return (a[row][col] + sum(a,row+1,0,RowLen,ColLen));
}
return (a[row][col] + sum(a,row, col+1,RowLen,ColLen));
}

Related

Adding each column in a 2D array which become values of the last row

I'm trying to add all of the values for each column in a 2D array and these sums become values that overwrite the last row of the array
for example:
4 5 6 7 8
1 2 3 4 5
0 0 0 0 0 //this row will be replaced by the sum of each column
4 5 6 7 8
1 2 3 4 5
5 7 9 11 13
public static void fillTotals(int[][] scores)
{
int count = 0;
for (int r = 0; r < scores.length - 1; r++)
{
scores[r][0] += count;
scores[scores.length - 1][scores[0].length - 1] = count;
}
}
I thought I could keep the columns the same and add it down with the changing rows but it isn't rewriting the last row. Also I don't know how to change the values at the bottom
You need to iterate once over all rows and columns, actually iterate over all rows, for every column. If you assume that the number of columns is the same for every row, then you can use scores[0].length as a fixed value.
public static void fillTotals(int[][] scores) {
for (int c=0; c < scores[0].length; ++c) {
int sum = 0;
for (int r=0; r < scores.length - 1; ++r) {
sum += scores[r][c];
}
scores[scores.length - 1][c] = sum;
}
}
This assumes that the final row of the 2D array is not part of the sum and is available to be overwritten with the sum of all preceding values, for each column.
Well, the reason that nothing is being updated is that you never change count, so you just end up adding 0 to everything. I think what you want instead of:
scores[r][0] += count;
is:
count += scores[r][0];
That way count will contain the summation of every element in the first column.
To be clear, scores[r][0] += count; is the same as scores[r][0] = scores[r][0] + count;, whereas I think you probably want count = scores[r][0] + count;
That being said, Im still pretty sure this code isnt actually going to work (sorry), since you only ever actually sum values from the first column. However, for the sake of not just doing way may be a school assignment for you, Im just going to leave it there. If you're still stuck let me know, and I'll try to help!

Dynamic Programming-RodCutting

I've recently started learning algorithms.
I tried to implement the classic Rod cutting problem using a Dynamic programming approach. I'm unable to get the correct output. Here is my code:
public class RodCuttingProblem {
public static void main(String[] args) {
int len=5;
int prices[]={2,5,7,3};
rodCuttingImplementation(prices,len);
}
public static void rodCuttingImplementation(int prices[],int len){
prices=reAdjustPrice(prices);
System.out.println("");
for(int i=0;i<prices.length;i++){
System.out.print(prices[i]+" ");
}
System.out.println(" ");
int dp[][]=new int[prices.length+1][len+1];
for(int i=1;i<prices.length;++i){
for(int j=1;j<=len;++j){
if(i<=j){
dp[i][j]=Math.max(dp[i-1][j], prices[i]+dp[i][j-1]);
}
else{
dp[i][j]=dp[i-1][j];
}
System.out.print(dp[i][j]+" ");
}
System.out.println();
}
System.out.println("Optimal Profit : "+dp[prices.length-1][len]);
}
static int[] reAdjustPrice(int prices[]){
int[] newPrices=new int[prices.length+1];
newPrices[0]=0;
for(int i=0;i<prices.length;i++){
newPrices[i+1]=prices[i];
}
return newPrices;
}
}
Output:
2 4 6 8 10
2 7 12 17 22
2 7 14 21 28
2 7 14 21 28
Optimal Profit : 28
As per my understanding, the output should be 12.
I really tried to understand what your algorithm is supposed to do, but I cannot, thus I cannot find out what the problem is
some concerns:
reAdjustPrice is doing very weird shift, I suppose you want to indicate that length is always >= 1 and thus index in array cannot be 0, it could work, though I suggest you to think in terms of 0-based arrays
you have array with 4 prices, but want to split rod with length 5. Usually this is done by appending 0 at the end of array, ie initial price for length 5 is 0
array dp - it has 2 dimensions, but maximal price for every length is 1 value, so you need 1 value for each step, this is for sure one dimensional array
Here is "canonical" implementation of rod splitting algorithm:
static int maxPrice(final int len, final int[] prices) {
// if len > prices.length, adjust it to have zeroes at the end
for (int i = 0; i < len; i++)
for (int j = 0; j < ((i + 1) >>> 1); j++)
prices[i] = Math.max(prices[i], prices[j] + prices[i - j - 1]);
return prices[len - 1];
}
note: this variant modifies input array, to decrease memory usage, but its very easy to modify it

Length and location of longest contiguous sequence of equal values where just before and just after are smaller

I have a problem that asks:
Write a program that converts its input arguments into an array of
integers, and then finds the length and location of the longest
contiguous sequence of equal values where the values of the elements
just before and just after this sequence are smaller.
For example, if
the command line arguments are “1 2 2 2 2 5 5 5 3” your program should
output the numbers 5 3 (the first number is a zero-based offset, and
the second number is the length of the subsequence). If a contiguous
subsequence appears at the beginning or end of the array, treat this
as a special case;e.g.,for input “5 5 5 5 3 8 8 8 1”your output should
be 0 4 (and not 5 3). If there are multiple subsequences that satisfy
the above condition, then output the first one.
Updated code:
public class LongestPlateau {
public static void main(String[] args) {
// TODO - Your solution
int N= args.length;
int [] array = new int [N];
int new_length=0;
int location=0;
int max=0;
int current_length=0;
//assign digits into array
for (int i=0; i < N; i++){
int number = Integer.parseInt(args[i]);
array [i] = number;
}
int compare=array[0];
for (int l=0; l<N; l++){
if (array[l] < compare){
current_length=0;
compare = array[l];
}
else if (array[l] == compare){
current_length+=1;
compare = array[l];
}
else if (array[l] > compare){
compare=array[l];
l++;
}
compare= array[l];
for (int b=0; b<N; b++){
if (current_length > max){
max = current_length;
location = array[l];
new_length=max-1;
}
else if (current_length==1){
new_length=max;
}
}
}
System.out.println(location);
System.out.println(new_length);
}
}
Issue is that for the input of "1 2 3 4" I continously get an Array Index out of bounds error.
Before you start writing code, try and think how a human would have solved it.
e.g.
For every item in the input, compare it to the previous, if it's larger, start a new sequence length check (write 0 in your notebook under - "current sequence length)), if it's the same, increase it by 1, if it's less, mark that sequence length as complete. if it's larger than your largest sequence length so far (started with 0) then this is now your largest sequence, if not, ignore that sequence length and move on to the next character. (or something like this)
write these instructions to yourself as a human, and try to follow them, and fix them as you find edge cases. Once you have a working human language algorithm, writing the code will be almost self driven.
You really need to post the specific issue you are seeing, how your actual results differ from your expected results, and what solutions you have attempted.
In any case, as for the general "how to proceed" question, I find that it often helps to work out these types of problems on paper first. Write down your sequence and step through it, observe what information you need to keep track of and what logic you need to apply to produce the desired results. Once you are able to do this, it will be far more straightforward to translate your clearly thought out algorithm into concrete code.
It appears you are at least somewhat on the right track parsing and storing your integer array, but you are a bit misguided with your [t+?] lookaheads. If you write this out and step through it by hand, you may be surprised at what you come up with.
Here is a full program description with test cases:
Given an array of integers int A[], find the length and location of the longest contiguous sequence of equal values for which the values of the elements just before and just after this sequence are smaller.
You should just print these two numbers (first is the length and second is the starting index of the plateau).
To complete the definition, we can consider there are imaginary index positions at A[-1] and A[A.length] where A[-1] < A[0] and A[A.length] < A[A.length-1]. Therefore, the plateau can start/end at both ends of array A. This condition guarantees the existence of a plateau. A plateau can be of length 1.
Example 1:
java LongestPlateau 1 2 2 2 2 1
With this command line arguments, program should print:
4
1
Example 2:
java LongestPlateau 1 2 2 2 2 3
With this command line arguments, program should print:
1
5
Example 2:
java LongestPlateau 3 2 2 2 1 2 1 1 1 2 2 0 1 1 1 1 0
With this command line arguments, program should print:
4
12
Example 2:
java LongestPlateau 3 2 2 2 2 2 2 1 2 1 1 1 2 2 0 1 1 1 1
With these command-line arguments, the program should print:
4
15
Here is my solution:
public class LongestPlateau {
private static int[] parseInputArray(String[] args) {
int[] value = new int[args.length+1];
for(int i = 0 ; i < args.length; i++){
if (i == args.length-1) value[i] = 0; // this imaginary last value of the array ensures that if the plateau is the last value of the array, then it outputs the correct answer
value[i] = Integer.parseInt(args[i]);
}
return value;
}
public static void printLargestPlateau(int[] values) {
int biggestStartIndex = -1;
int biggestLength = 0;
int currentIndex = 1;
int currentPlateauStartIndex = 1;
int currentLength = 1;
boolean plateauStarted = false;
while (currentIndex < values.length) {
if(isStartOfPlateau(currentIndex, values)){
currentLength = 1;
plateauStarted = true;
currentPlateauStartIndex = currentIndex;
} else if (isEndOfPlateau(currentIndex, values)) {
if(plateauStarted && currentLength > biggestLength){
biggestLength = currentLength;
biggestStartIndex = currentPlateauStartIndex;
}
plateauStarted = false;
currentLength = 1;
} else {
currentLength++;
}
currentIndex++;
}
System.out.println(biggestLength +"\n"+biggestStartIndex);
}
private static boolean isStartOfPlateau(int index, int[] values){
if(index <= 0){
return false;
}
return values[index-1] < values[index];
}
private static boolean isEndOfPlateau(int index, int[] values){
if(index <= 0){
return false;
}
return values[index - 1] > values[index];
}
public static void main(String[] args) {
int[] values = parseInputArray(args);
printLargestPlateau(values);
}
}

Display minor matrix 3 x 3

I want to display minor of a matrix.
First, I have a matrix 3 x 3.
1 2 3
4 5 6
7 8 9
I want to display M11 (delete row 1 and col 1) so it's like
1 3
7 9
But with my program I got something like this
1 2
4 0
Here is my code :
public static double [][] Minor (double [][] M, int bar, int kol, int maxidx){
double [][] minor = new double [2][2];
int mini=0, minj=0;
for (int i=0; i<2;i++){
for (int j=0;j<2;j++){
if (i!=bar | j!=kol){
minor[mini][minj]=M[i][j];
minj++;
if (minj==(maxidx-1)){
mini++;
minj=0;
}
}
}
}
return minor;
}
For display the minor I used this code :
for (int i=0;i<2;i++){
for (int j=0;j<2;j++){
System.out.print(Minor(M,1,1,3)[i][j]+" ");
}
System.out.println();
}
What's wrong with my code?
if (i!=bar | j!=kol)
this | is bitwise operator not logical operator
however, your whole logic is wrong
do this
for (int i=0; i<=2;i++){
if(i!=bar)
{
for (int j=0;j<=2;j++){
if (j!=kol){
minor[mini][minj]=M[i][j];
minj++;
}
}
mini++;
}
}
}
I think this if (i!=bar | j!=kol){ is a problem. You should use || (logic or)
You are using bitwise OR where you should be using logical AND:
if (i!=bar && j!=kol){
^^
Right now you are only skipping the element at the intersection of bar and kol. Instead, you want to be skipping the entire bar row and the entire kol column.
As said in comments, that sounds overkill to loop through the 3x3 matrix just to pick numbers into a 2x2.
/** ?skip : which is the first row/column we should keep (0/1)
** ?last : shall we skip the last item of the row/column.
**/
public static double [][] MyMinor (double [][] M, int vskip, int vlast, int hskip, int hlast){
double [][] minor = new double [2][2];
int mini=0, minj=0;
minor[0][0]=M[vskip][hskip];
minor[0][1]=M[vskip][2-hlast];
minor[1][0]=M[2-vlast][hskip];
minor[1][1]=M[2-vlast][2-hlast];
return minor;
}
// to remove any bar/kol combo:
MyMinor(input,bar==0?1:0,bar==2?1:0,kol==0?1:0,kol==2?1:0);
First if we are trying to remove middle row and column I think your expected result would be:
1 3
7 9
So then I would say this is the code you are looking for:
public static double [][] Minor (double [][] M, int bar, int kol, int maxidx){
double [][] minor = new double [2][2];
int mini=0, minj=0;
for (int i=0; i<3;i++){
for (int j=0;j<3;j++){
if (i!=bar && j!=kol){
minor[mini][minj]=M[i][j];
minj++;
if (minj==(maxidx-1)){
mini++;
minj=0;
}
}
}
}
return minor;
}
Problem was with for loops: for (int i=0; i<2;i++) and for (int j=0;j<2;j++). As you can see it would never reach 3rd row and column in M so you will not be able to have result you expect. And also in your code
if (i!=bar | j!=kol)
should be replaced with
if (i!=bar && j!=kol) as you do not need any elements from both 'bar' row and 'kol' column.

print how many rows contains consecutive elements matching a+b=c

I'm trying to print how many rows contain subarrays (a, b, c) which satisfy a + b = c
int [][] matrix = {
{0,**5,2,7**,0,0},
{6,0,2, 1,-5,5},
{8,5,**1,1,2**,-2},
{3,-1,-5,-3,-4,-2}
};
this is the matrix in question it has only two sums so my program should print 2 , but somehow i miss something , the program should only print the rows that contain a sum of numbers not matter how many they are on a row
int [][] matrix = {
{0,5,2,7,9,0},
{6,0,2, 1,-5,5},
{8,5,1,1,2,-2},
{3,-1,-5,-3,-4,-2}
};
for example here we have 3 sums, but my program should print 2 anyway
public static int rowSumsOfThree(int [][] matrix) {
int count = 0 ;
if (matrix.length != 0 ) {
for (int i = 0 ; i < matrix.length ; i++) {
for (int j = 0 ; j < matrix[0].length-2 ; j++)
if (matrix[i][j] + matrix[i][j+1] == matrix[i][j+2]) {
count++;
break;
}
}}
return count;
}
this is my code so far , i know it's maybe some stupid mistake i make , if you can provide some explanation it is greatly appreciated , thank you all
Maybe my english is bad , I need to create a method that sums the elements within an array as
int [] matrix = {{2,3,4,7,8,3,2},
{1,23,4,2,2,}};
given this matrix , i need to sum them like this , first two elements = the third , second and third element = the fourth and so on , if the algorithm checks than it should return on how many rows it checks , first matrix should be 2 , second matrix should be 1 ; i hope i explained better
EDIT : Use of break solved my problem ! It will count only one sum per row , even if there are more per row , therefor count will be equal also to the numbers of rows. thank you for the help
As ari said, your return statement should be:
return count;
not
return rowIndex;
It's a very simple bug, consider deleting your question.

Categories

Resources