1. ## loop question

Hi,

Im still very new to programming in general and
i wrote some code which doesnt quite work the way i want it

my aim here is to get it to find the minimum in the array and modify the array accordingly, then i want it to take the modified array and find the new minimum and so on

up till now i wrote something that finds the minimum and modifies the array but i dont know how to get it to reuse the modified array to find the new minimum...

heres what i've done:

Code:
#include "stdafx.h"
#include<stdio.h>

int minimum(int array1[3][3]);

int _tmain(int argc, _TCHAR* argv[])
{
int array1[3][3]={{  0,113,303},
{113,  0,196},
{303,196,  0}};

int i;
int j;
int ii;
int key=minimum(array1);

/*------------------------------------------------------------*/

for(i=0;i<=2;i++){

for (j=0;j<=2;j++){
/* check if min exists check min by col */

if(array1[i][j]==key){
for (ii=0;ii<3;ii++) array1[ii][j]=0;

/* because of symmetric matrix
when the first minimum is found
set its column to zero*/

array1[j][i]=0;

/* set the next identical minimum to
zero */

break;

}

}
break;

}
/* print array */
for(i=0;i<=2;i++){

for (j=0;j<=2;j++){
printf("%4d ",array1[i][j]);
}
printf("\n");
}
scanf("%d",&i);

return 0;
}

/*--------------------------------------------------------------------*/

/* find the minimum */
int minimum(int array1[3][3]){
int i; /* i counter */
int j; /* j counter */
int M=999; /* initialise to the highest possible distance */

/* loop through rows of distance */
for (i=0; i < 3; i++){
/*loop through columns of distance */
for (j=0; j < 3; j++){
if (array1[i][j]<M && array1[i][j]!=0){
M=array1[i][j];

}
}
}
return M;
}

2. You could probably add something to minimum() so you use it recursively -- that is, call itself like this:
Code:
int minimum (int array) {
blah, blah
if (condition) minimum(array);
}

3. so i could say that at the end i end up with a different array and where you put the if make it check that the newArray doesnt much the previous one so it could repeat itself?

4. Originally Posted by goofy26
so i could say that at the end i end up with a different array and where you put the if make it check that the newArray doesnt much the previous one so it could repeat itself?
Yeah. It will repeat recursively that way until it has accomplished the final, finished array.

Code:
#include <stdio.h>

int recursive_function (int *x) {
if (*x==5) return *x;
printf("x is now %d\n",*x); fflush(stdout);
*x+=1;
return recursive_function (x);
}

int main() {
int a=0;
recursive_function(&a);
printf ("a is %d!\n",a);
return 0;
}

Output:
x is now 0
x is now 1
x is now 2
x is now 3
x is now 4
a is 5!

5. thanks for the example i will try to change it and post back

6. im sure im doing something wrong to it...

i've put an if in the minimum function to repeat it as long as array1 is not 0

heres what i have but i get an error back

Code:
#include "stdafx.h"
#include<stdio.h>

int minimum(int array1[3][3]);

int _tmain(int argc, _TCHAR* argv[])
{
int array1[3][3]={{  0,113,303},
{113,  0,196},
{303,196,  0}};

int i;
int j;
int ii;

int key=minimum(array1);

/*------------------------------------------------------------*/

for(i=0;i<=2;i++){

for (j=0;j<=2;j++){
/* check if min exists check min by col */

if(array1[i][j]==key){
for (ii=0;ii<3;ii++) array1[ii][j]=0; /* because of symmetric matrix
when the first minimum
is found set its column
to zero*/

array1[j][i]=0;/* set the next identical minimum to zero */

break;

}

}
break;

}

/* print array */
for(i=0;i<=2;i++){

for (j=0;j<=2;j++){
printf("%4d ",array1[i][j]);
}
printf("\n");
}
scanf("%d",&i);

return 0;
}

/*--------------------------------------------------------------------*/

/* find the minimum */
int minimum(int array1[3][3]){
int i; /* i counter */
int j; /* j counter */
int M=9999; /* initialise to the highest possible distance */

if (array1!=0){

/* loop through rows of distance */
for (i=0; i < 3; i++){
/*loop through columns of distance */
for (j=0; j < 3; j++){

if (array1[i][j]<M && array1[i][j]!=0){
M=array1[i][j];

}
}
}

return minimum(array1);
}

}

7. I have changed it again and the recursion now works but the problem lies when it finds the second minimum which in this case is 196 and goes through the loop to change the values it doesnt change them....

Code:
#include "stdafx.h"
#include<stdio.h>
void printArray(int a[3][3]);
int sum_array(int array1[3][3]);
int minimum(int array1[3][3]);

int _tmain(int argc, _TCHAR* argv[])
{
int array1[3][3]={{  0,113,303},
{113,  0,196},
{303,196,  0}};

int i;
int j;
int ii;

/*------------------------------------------------------------*/
printf("%d\n\n",sum_array(array1));
printArray(array1);

while(sum_array(array1)!=0){
printArray(array1);
printf("%d\n",minimum(array1));
for(i=0;i<=2;i++){
for (j=0;j<=2;j++){
/* check if min exists check min by col */
if(array1[i][j]==minimum(array1)){
for (ii=0;ii<3;ii++) array1[ii][j]=0; /* because of symmetric matrix
when the first minimum
is found set its column
to zero*/

array1[j][i]=0;/* set the next identical minimum to zero */
printArray(array1);
break;
}
}
break;
}
}
printArray(array1);
printf("%d\n",sum_array(array1));
scanf("%d",&i);
return 0;
}

/*--------------------------------------------------------------------*/
/* print array */
void printArray(int a[3][3])
{
int i;
int j;
for(i=0;i<=2;i++){

for (j=0;j<=2;j++){
printf("%4d ",a[i][j]);
}
printf("\n");
}
printf("\n");
}

/* find the minimum */
int minimum(int array1[3][3]){
int i; /* i counter */
int j; /* j counter */
int M=9999; /* initialise to the highest possible distance */

/* loop through rows of distance */
for (i=0; i < 3; i++){
/*loop through columns of distance */
for (j=0; j < 3; j++){

if (array1[i][j]<M && array1[i][j]!=0){
M=array1[i][j];

}
}

}

return M;
}

int sum_array(int array1[3][3])
{
int i;
int j;
int sum=0;
for (i=0; i < 3; i++){
/*loop through columns of distance */
for (j=0; j < 3; j++){

sum = sum + array1[i][j];
}
}
return(sum);
}

8. The way you have it now, minimum() will never return -- it will just call itself over and over forever. You need two return statements -- one to continue the recursion, which you have, but one BEFORE that which depends on some condition. I don't know what that condition is, because your original goal kind of sounds like it will go on forever too:
my aim here is to get it to find the minimum in the array and modify the array accordingly, then i want it to take the modified array and find the new minimum and so on

up till now i wrote something that finds the minimum and modifies the array but i dont know how to get it to reuse the modified array to find the new minimum...
Tho I guess there will be a real "minimum" and obviously you must have some point in mind at which the array has been modified for the last time. Notice in the example I gave you, the process is complete when x==5. You also need this form of conditional return -- one that returns a definite real number or whatever, so that the recursion can stop somewhere. I presume that will be when minimum() doesn't need to make any changes to array1.

Since the purpose is not clear to me, I can't tell you where, but this will probably just be an appropriate else statement (eg, "} else return M") BEFORE the final return which is the catch-all (it might be easier or better to do it the other way around, ie. make the recursion conditional and "return M" the catch-all. Recursion is a pliable concept).

9. yeah the minimum will stop when all values in array 1 is equal to zero

so you are saying to put an if in the minimum function before the for loops ...something like if (sum_array(array1)!=0) ?

im not sure what you mean by putting the return M in the else clause....

should i put 2 return M???

update
following ur example
ive put it like this but its still trapped
im not sure if i wrote something wrong....

Code:
/* find the minimum */
int minimum(int array1[3][3]){
int sum_array(int array1[3][3]);

int i; /* i counter */
int j; /* j counter */
int M=9999; /* initialise to the highest possible distance */
if (sum_array(array1)==0) return sum_array(array1);
/* loop through rows of distance */
for (i=0; i < 3; i++){
/*loop through columns of distance */
for (j=0; j < 3; j++){

if (array1[i][j]<M && array1[i][j]!=0){
M=array1[i][j];

}
}
}

return M;

}

10. Oh dear! I just noticed our last two posts crossed and you had removed the recursion in minimum(). Anyway, what I am thinking if
the minimum will stop when all values in array 1 is equal to zero
would be something like this, using a flag to indicate when the process is complete:
Code:
int minimum(int array1[3][3]){
char flag=0;    /* one byte "boolean" flag */
int i; /* i counter */
int j; /* j counter */
int M=9999; /* initialise to the highest possible distance */

if (array1!=0){

/* loop through rows of distance */
for (i=0; i < 3; i++){
/*loop through columns of distance */
for (j=0; j < 3; j++){

if (array1[i][j]<M && array1[i][j]!=0){
M=array1[i][j];
flag=1; /* set flag to true is change made */

}
}
}

}
if (flag) return minimum(array1);  /* flag is TRUE */
else return M;  /* flag is still false, M is still 9999 */

}
But hold it -- that means you won't get the value of the actual minimum. So maybe change those last two lines to this:
Code:
if (flag) {      /* flag is TRUE */
j=minimum(array1); /* reuse int j */
if (j==9999) return M;  /* this will only happen once */
else return j;
}
else return M;  /* flag is still false, M is still 9999 */
/* (that will also only happen once) */

11. I've put that in but now i get an error saying stack overflow

before giving me this error i was stepping into the code and notice that it would find the first minimum (113) and do the changes, then found the second minimum (196) but get trapped in the loop of the main programm and not do any changes to the array

here's all of it:

Code:
#include "stdafx.h"
#include<stdio.h>
void printArray(int a[3][3]);
int sum_array(int array1[3][3]);
int minimum(int array1[3][3]);

int _tmain(int argc, _TCHAR* argv[])
{
int array1[3][3]={{  0,113,303},
{113,  0,196},
{303,196,  0}};

int i;
int j;
int ii;

/*------------------------------------------------------------*/
printf("%d\n\n",sum_array(array1));
printArray(array1);

while(sum_array(array1)!=0){
printArray(array1);
printf("%d\n",minimum(array1));
for(i=0;i<=2;i++){
for (j=0;j<=2;j++){
/* check if min exists check min by col */
if(array1[i][j]==minimum(array1)){
for (ii=0;ii<3;ii++) array1[ii][j]=0; /* because of symmetric matrix
when the first minimum
is found set its column
to zero*/

array1[j][i]=0;/* set the next identical minimum to zero */
printArray(array1);
break;
}
}
break;
}
}
printArray(array1);
printf("%d\n",sum_array(array1));
scanf("%d",&i);
return 0;
}

/*--------------------------------------------------------------------*/
/* print array */
void printArray(int a[3][3])
{
int i;
int j;
for(i=0;i<=2;i++){

for (j=0;j<=2;j++){
printf("%4d ",a[i][j]);
}
printf("\n");
}
printf("\n");
}

/* find the minimum */
int minimum(int array1[3][3]){

char flag=0;    /* one byte "boolean" flag */

int i; /* i counter */
int j; /* j counter */
int M=9999; /* initialise to the highest possible distance */
if (array1!=0) {
/* loop through rows of distance */
for (i=0; i < 3; i++){
/*loop through columns of distance */
for (j=0; j < 3; j++){

if (array1[i][j]<M && array1[i][j]!=0){
M=array1[i][j];
flag=1; /* set flag to true is change made */

}
}
}
}

if (flag) {      /* flag is TRUE */
j=minimum(array1); /* reuse int j */
if (j=9999) return M;  /* this will only happen once */
else return j;
}
else return M;  /* flag is still false, M is still 9999 */
/* (that will also only happen once) */

}

int sum_array(int array1[3][3])
{
int i;
int j;
int sum=0;
for (i=0; i < 3; i++){
/*loop through columns of distance */
for (j=0; j < 3; j++){

sum = sum + array1[i][j];
}
}
return(sum);
}

12. Code:
if (j=9999) return M;  /* this will only happen once */
else return j;
So if 9999 is not zero [which is likely], we return M?

--
Mats

13. Originally Posted by goofy26
I've put that in but now i get an error saying stack overflow
A stack overflow occurs in endless recursion. That's because you actually didn't change the array.

You might want to isolate the minimum function and work with it in it's own program. I just did that and realized a couple of things that needed changing for it to work:
Code:
#include <stdio.h>

void showray (int ray[3][3]) { /* for debugging */
int i;
puts("-----");
for (i=0;i<3;i++) printf("%d %d %d\n",ray[i][0],ray[i][1],ray[i][2]);
}

int minimum(int array1[3][3]){
int i; /* i counter */
int j; /* j counter */
int r; /* used for return value */
int M=9999; /* initialise to the highest possible distance */

showray(array1);
/* loop through rows of distance */
for (i=0; i < 3; i++){
/*loop through columns of distance */
for (j=0; j < 3; j++){

if ((array1[i][j]<M) && (array1[i][j]!=0)){
M=array1[i][j];
array1[i][j]=0;  /* oops! */
r=minimum(array1); /* reuse int j */
if (r==9999) return M;  /* this will only happen once */
else return r;
}
}
}
return M;
}

int main() {
int array1[3][3]={{  0,113,303}, {113,  0,196}, {303,196,  0}};
printf("\nfinal return: %d\n",minimum(array1));
return 0;
}
Notice the use of nested brackets when doing this multiple truth test!
If you don't actually change array1, this is just the same thing over and over.
r=9999 was a typo from my previous post, sorry.
After that, you can go straight into the recursion (no more flag). If you want to start with the highest or lowest value and progress that way, that will be more complicated -- but it might allow you to return the real lowest value in the end, which this just finishes with the last value changed in the matrix:
Code:
[root~/C] ./a.out
-----
0 113 303
113 0 196
303 196 0
-----
0 0 303
113 0 196
303 196 0
-----
0 0 0
113 0 196
303 196 0
-----
0 0 0
0 0 196
303 196 0
-----
0 0 0
0 0 0
303 196 0
-----
0 0 0
0 0 0
0 196 0
-----
0 0 0
0 0 0
0 0 0

final return: 196
However, I think it would be easier to just leave it as is and use a global variable to get the lowest value (if you need it).

On the other hand, getting the absolute lowest value each time would be truer to your original intentions. I think to do that you will have to put the flag back in, and TWO more variables to keep the i and j coordinates of M, then set the M location to zero (instead of just setting the first one found).

14. ah....yes the brackets are wrong

i thought i needed to make the change in main rather than the minimum function....