I tried this in many ways, it would've been much easier if I could use iteration instead of recursion, but this is the assignment.
So far, I've come with the idea to separate the sum. One function to make the sum of a colum recursively, and to call that function so I can add all the sums into another function to get the total. Can anyone help me with my code or if you have a better/simpler idea, please share.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
float sum_colum(float b[], int m){
float result;
if (m == 0)
result = 0;
else
result = sum_colum(b, m-1) b[m-1];
return result;
}
float sum_total(float a[][100], int n, int m){
float f = 0;
int i = 1;
float col = sum_colum(b, );
while(i <= n){
f = col[i];
n--;
}
return f;
}
void main(){
float x[100][100];
int i, j, n, m;
printf("Number of rows: "); scanf("%d", &n);
printf("Number of colums: "); scanf("%d", &m);
for(i=0; i<n; i ){
for(j=0; j<m; j ){
printf("x[%d][%d] = ", i, j);
scanf("%f", &x[i][j]);
}
}
printf("The sum of elemets of a 2D array is: %.2f", sum_total(x, n, m));
}
CodePudding user response:
- Solve recurse solution for an
1D
Array. Recursion begins at the end (last index of row), stops when it hits the first element at0
index. In a 2D matrix every row is an1D
Array.
float sum_row (float row[], int ci) {
return (0 == ci) ? row[ci] : row[ci] sum_row (row, ci - 1) ;
}
- Now extend that logic to every row in the matrix. Again we recurse from last row and stop when we arrive at row-index
0
.
float sum_matrix (float mat[][MAX_COLS], int ri, int cols) {
if (0 == ri)
return sum_row (mat[0], cols);
else
return sum_row (mat[ri], cols) sum_matrix (mat, ri -1, cols);
}
Now to test it, since C
array-indexes begin at 0
we pass MAX_ROWS-1
& MAX_COLS-1
as highest values row-index
& column-index
can take respectively.
When you read rows
& columns
values from the user, then you'll use:
float sum = sum_matrix (mat, rows - 1, columns - 1);
#include <stdio.h>
#define MAX_ROWS 10
#define MAX_COLS 10
int main() {
float mat[MAX_ROWS][MAX_COLS];
for (int ri = 0; ri < MAX_ROWS; ri) {
for (int ci = 0; ci < MAX_COLS; ci) {
mat[ri][ci] = (float) ri * ci;
printf (".6f ", mat[ri][ci]);
}
putchar('\n');
}
float sum = sum_matrix(mat, MAX_ROWS-1, MAX_COLS-1);
printf ("2D Matrix Sum with Recursion: %f\n", sum);
}
Note:
- Recursion is not advised when an iterative solution is cheaper on resources (time space).
- If matrix float values are too large( /-),
sum
may overflow/underflow. You may want to usedouble
storage forsum
; and both function shall return adouble
value. As of today in mainstream systems,double
(using 8 bytes) can store larger range of values as opposed tofloat
(4 bytes).
CodePudding user response:
Recursion is pretty much always the wrong solution to any problem: it is slow, dangerous, memory consuming and often needlessly hard to read or implement.
That being said, there's a rather simple way to do this and that's to "mangle" the 2D array into a 1D one. All items are guaranteed to be allocated adjacently. (There's some language lawyer aspects of addressing an inner array out of bounds, but I'll ignore them since recursion is bad practice to begin with.)
float sum (size_t size, float arr[size])
{
return size==0 ? 0.0f :
arr[size-1] sum(size-1, arr);
}
You'd call it like this:
int main (void)
{
float x[3][3] =
{
{1.0f, 2.0f, 3.0f},
{4.0f, 5.0f, 6.0f},
{7.0f, 8.0f, 9.0f},
};
printf("sum: %f\n", sum(9, (float*)x));
}
The resulting machine code is some horrible parallization goo where some compilers fail to tail-call optimize/inline even with main() in the same translation unit. This with my version which is much more efficient than one breaking down the array in rows and columns. One of the main problems here is that the recursion can't predict when it will end since it apparently can't tell the size at compile-time (gcc seems to do a better job than clang here, but the machine code is very difficult to read).
Now compare that utter crap with a plain loop:
float sum=0;
float* ptr = (float*)x;
for(size_t i=0; i<9; i )
sum =ptr[i];
Resulting in this nicely optimized asm:
.LCPI0_0:
.quad 0x4046800000000000 # double 45
main: # @main
push rax
movsd xmm0, qword ptr [rip .LCPI0_0] # xmm0 = mem[0],zero
mov edi, offset .L.str
mov al, 1
call printf
xor eax, eax
pop rcx
ret
.L.str:
.asciz "sum: %f\n"
From this we can conclude that using recursion wasn't just a bad idea, it was complete madness. I would ask your teacher why they are teaching you how to write bad programs instead of focusing on how to write good programs.