#java #arrays #recursion
#java #массивы #рекурсия
Вопрос:
Эй, ребята, у меня возникли проблемы с написанием этой части моего кода. Я должен суммировать элементы этого 2-мерного массива с помощью рекурсии. Я понимаю, что мне нужно сделать, но я не понимаю, как реализовать это для пошагового просмотра массива. Я продолжаю получать ошибки. Не мог бы кто-нибудь мне помочь?
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 );
}
}
Комментарии:
1. Вы говорите «без рекурсии», а затем приведенный вами пример является рекурсивным методом. Вы на самом деле просто хотите итеративное решение?
2. В вашем примере используется рекурсия (sum2D вызывает sum2D). Итак, у вас уже есть 2-мерный массив? И если да, вам просто нужно знать, как выполнить итерацию по нему с помощью for-цикла?
3. Мне нужно добавить элементы без использования цикла for во время цикла или чего-либо подобного. Я должен продолжать вызывать метод sum2D, чтобы добавить все элементы
4. В этом случае вы не имеете в виду «без рекурсии», вы имеете в виду с рекурсией.
5. циклы for — это «итерация». Вызов функции внутри себя является рекурсией.
Ответ №1:
Основной план, когда вам нужно рекурсивное решение, заключается в поиске способа разбить проблему так, чтобы она содержала меньшую проблему (или более одной меньшей проблемы), которая выглядит точно так же, как исходная проблема, только меньшего размера.
Для 2-мерного массива это может быть сложно. Допустим, ваш массив выглядит так
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
Первой мыслью может быть написать рекурсивную функцию, которая принимает row
и column
и добавляет a[row][column]
к сумме остальной части массива. Проблема в том, что если, например, row=0
и column=0
, «меньшая проблема», которую вам нужно решить, выглядит так
---------------------
1 | 2 3 4 5 |
--- |
| 6 7 8 9 10 |
| 11 12 13 14 15 |
-------------------------
(пожалуйста, извините за плохое оформление ASCII). Итак, теперь ваша меньшая проблема вообще не похожа на массив, а на какой-то странный многоугольник. Этот подход все еще можно использовать, написав рекурсивную функцию типа
int sumOfWeirdShapedSectionOfArray(int[][] array, int firstRow, int firstCol)
Но это определенно злоупотребление рекурсией. Лучше было бы разбить массив на «первую строку» и «остальные строки»:
1 2 3 4 5
-------------------------
| 6 7 8 9 10 |
| 11 12 13 14 15 |
-------------------------
(Или вы можете разбить его на «последнюю строку» и «остальные строки».)
Теперь ваша меньшая проблема очень похожа на исходную проблему, верно? Итак, ваш ответ будет таким: «сумма элементов в массиве равна сумме первой строки плюс сумма элементов в меньшем массиве, начиная со следующей строки». Вторая часть этого — рекурсивный вызов. Первая часть, сумма первой строки, потребует, чтобы вы вызвали новую функцию для сложения строки; и поскольку вам все еще не разрешено использовать циклы, функция «сложить строку» также будет рекурсивной, но это должно быть легко.
Сказав все это, никто никогда не будет использовать рекурсию в реальном мире для решения этой проблемы. Однако, если цель состоит в том, чтобы ознакомиться с рекурсией, чтобы вы могли использовать ее, когда это требуется, тогда вам нужно следовать такому мыслительному процессу.
Комментарии:
1. Спасибо за помощь! Это было сказано лучше, чем объяснил мой профессор. Я понял свою ошибку после того, как на нее указали, но это очень помогает. По крайней мере, вы пытаетесь помочь мне, дав мне несколько советов, вместо того, чтобы быть снисходительным придурком, как некоторые другие.
Ответ №2:
Чтобы сделать это без рекурсии, просто создайте два вложенных цикла for:
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;
Чтобы сделать это с помощью рекурсии:
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);
}
По сути, вы делаете то же самое: просматриваете каждую строку и столбец и добавляете их вместе.
Однако обратите внимание, что существует ограничение на количество рекурсивных подпрограмм, которые вы можете использовать. Если вы повторите слишком глубоко, вы получите ошибку StackOverflow.
Комментарии:
1. Итак, у меня есть исключение stackoverflowexception в if(строка == a.длина).
2. @osiris2190 Насколько велик ваш массив? Или подождите, я забыл вычесть один… РЕДАКТИРОВАТЬ: Да, это должно быть.length-1
3. мой массив — это массив [3] [4], в который пользователь вводит 12 целочисленных элементов, если это помогает решить проблему.
4. Я опубликовал обновленный код, включающий основную функцию. Все еще выдает ошибку
5. @osiris2190 Исправил это. Проблема в том, что вы не можете использовать
row
илиcol
. Вам нужно использоватьrow 1
илиcol 1
.
Ответ №3:
Базовое условие было неверным в приведенном выше коде:
Вот код, который работает:
public static int addMatrix(int a[][],int r,int c){
if(r==a.length-1 amp;amp; 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);
}
Ответ №4:
Эквивалентная программа «C» здесь, но для количества строк 4 и количества столбцов 1 я получаю непредсказуемый результат, почему?
#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",amp;nrow);
printf("Enter No of Columns:");
scanf("%d",amp;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",amp;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) amp;amp; (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));
}
Комментарии:
1. Это похоже на вопрос, а не на ответ. Возможно, задайте новый вопрос?
2. Я сам получил ответ на свой вопрос, пытаясь: «C» (может быть, какой-то компилятор) не поддерживает передачу двумерного массива переменных в качестве формальных параметров. Итак, в приведенном выше коде «C» мне нужно было удалить int a[row][col] в функции sum и изменил его, чтобы иметь только длину столбца, которая фиксирована. Вот оно: int sum(int m,int n,int a[][n],int row,int col). m — длина строки, а n — длина столбца, оба являются фиксированными.