Recursive Function

C

cplusplusquestion

As discussion last time, I am thinking if it is possible to change the
recursive function from:

void fun(Array a){
for (int i=0; i<MAX1; i++)
for(int j=0; j<MAX2; j++){
if ( a[j] != -1) {
/*... using a[j] to calculate some value...*/
a[j]=-1;
fun(a);
}
}

to:

void fun(Array& a){
/*......*/
}

and make sure the result will be same.
 
D

Daniel Pitts

As discussion last time, I am thinking if it is possible to change the
recursive function from:

void fun(Array a){
for (int i=0; i<MAX1; i++)
for(int j=0; j<MAX2; j++){
if ( a[j] != -1) {
/*... using a[j] to calculate some value...*/
a[j]=-1;
fun(a);
}
}

to:

void fun(Array& a){
/*......*/
}

and make sure the result will be same.

Its depends.
If you could re-write it as:

void fun(Array a) {
for (int i=0; i<MAX1; i++) {
for (int j=0; j<MAX2; j++) {
if ( a[j] != -1) {
calculateSomeValue(a[j]);
a[j]=-1;
fun(a);
}
}
}
}

Then it would be trivial. Just remove the "fun(a)" call, since it isn't
actually doing anything productive.

Now, if you need to pass more information into calculateSomeValue to
make it work, let us know what and why.
 
G

Greg Herlihy

As discussion last time, I am thinking if it is possible to change the
recursive function from:
void fun(Array a){
    for (int i=0; i<MAX1; i++)
        for(int j=0; j<MAX2; j++){
               if ( a[j] != -1) {
                   /*... using a[j] to calculate some value...*/
                   a[j]=-1;
                   fun(a);
       }
}

void fun(Array& a){
   /*......*/
}

and make sure the result will be same.

Its depends.
If you could re-write it as:

  void fun(Array a) {
    for (int i=0; i<MAX1; i++) {
     for (int j=0; j<MAX2; j++) {
       if ( a[j] != -1) {
         calculateSomeValue(a[j]);
         a[j]=-1;
         fun(a);
       }
     }
    }
  }

Then it would be trivial. Just remove the "fun(a)" call, since it isn't
actually doing anything productive.


How do you figure? Without knowing how "Array" is defined, it is not
possible for us to tell whether the call to fun(a) serves any useful
purpose or not. For example, one could imagine a more complete program
fragment - and one for which it is clear that the call to fun(a) is
useful:

const int MAX1 = 16;
const int MAX2 = 32;

typedef int (&Array)[MAX1][MAX2];

void fun(Array a)
{
for (int i = 0; i < MAX1; i++)
for (int j = 0; j < MAX2; j++)
if (a[j] != -1)
{
calculateSomeValue(a[j]);
a[j] = -1;
fun(a);
}
}

Greg
 
D

Daniel Pitts

Greg said:
As discussion last time, I am thinking if it is possible to change the
recursive function from:
void fun(Array a){
for (int i=0; i<MAX1; i++)
for(int j=0; j<MAX2; j++){
if ( a[j] != -1) {
/*... using a[j] to calculate some value...*/
a[j]=-1;
fun(a);
}
}
to:
void fun(Array& a){
/*......*/
}
and make sure the result will be same.

Its depends.
If you could re-write it as:

void fun(Array a) {
for (int i=0; i<MAX1; i++) {
for (int j=0; j<MAX2; j++) {
if ( a[j] != -1) {
calculateSomeValue(a[j]);
a[j]=-1;
fun(a);
}
}
}
}

Then it would be trivial. Just remove the "fun(a)" call, since it isn't
actually doing anything productive.


How do you figure? Without knowing how "Array" is defined, it is not
possible for us to tell whether the call to fun(a) serves any useful
purpose or not. For example, one could imagine a more complete program
fragment - and one for which it is clear that the call to fun(a) is
useful:

const int MAX1 = 16;
const int MAX2 = 32;

typedef int (&Array)[MAX1][MAX2];

void fun(Array a)
{
for (int i = 0; i < MAX1; i++)
for (int j = 0; j < MAX2; j++)
if (a[j] != -1)
{
calculateSomeValue(a[j]);
a[j] = -1;
fun(a);
}
}

Greg


Lets walk through the program shall we...
first, calculateSomeValue(a[0][0]) gets called.
a[0][0] = -1;
call to fun(a)

a[0][0] == -1, so it skips
calculateSomeValue(a[0][1]) gets caled
a[0][1] = -1;
call to fun(a)
a[0][0] and a[0][1] get skipped.... See where I'm going? If you don't
call fun(a), the same calculations will get done, minus the overactive
recursion and extra comparisons to -1

So, the call to fun(a) is still not useful. If you replace
calculateSomeValue with std::cout << i << ", " << j << ": " << a[j]
<< std::endl; You will see that the output is the same with or without
fun(a), but significantly more efficient without it.
 
C

cplusplusquestion

How do you figure? Without knowing how "Array" is defined, it is not
possible for us to tell whether the call to fun(a) serves any useful
purpose or not. For example, one could imagine a more complete program
fragment - and one for which it is clear that the call to fun(a) is
useful:

    const int MAX1 = 16;
    const int MAX2 = 32;

    typedef int (&Array)[MAX1][MAX2];

    void fun(Array a)
    {
        for (int i = 0; i < MAX1; i++)
            for (int j = 0; j < MAX2; j++)
                if (a[j] != -1)
                {
                    calculateSomeValue(a[j]);
                    a[j] = -1;
                    fun(a);
                }
    }

Greg


Here is my example code:

********************************************************************************
#include <iostream>

using namespace std;

struct Array{
int n[3][3];
};

void fun(Array a)
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (a.n[j] != -1)
{
// calculateSomeValue(a[j]);
cout << i << " " << j << " " << a.n[j] << endl;
a.n[j] = -1;
fun(a); //with it and without it will be different
}
}

int main(){
Array b;

for(int i=0; i<3; i++)
for(int j=0; j<3; j++){
b.n[j] = i+j;
}

fun(b);
}
******************************************************************************
 
D

Daniel Pitts

How do you figure? Without knowing how "Array" is defined, it is not
possible for us to tell whether the call to fun(a) serves any useful
purpose or not. For example, one could imagine a more complete program
fragment - and one for which it is clear that the call to fun(a) is
useful:

const int MAX1 = 16;
const int MAX2 = 32;

typedef int (&Array)[MAX1][MAX2];

void fun(Array a)
{
for (int i = 0; i < MAX1; i++)
for (int j = 0; j < MAX2; j++)
if (a[j] != -1)
{
calculateSomeValue(a[j]);
a[j] = -1;
fun(a);
}
}

Greg


Here is my example code:

********************************************************************************
#include <iostream>

using namespace std;

struct Array{
int n[3][3];
};

void fun(Array a)
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (a.n[j] != -1)
{
// calculateSomeValue(a[j]);
cout << i << " " << j << " " << a.n[j] << endl;
a.n[j] = -1;
fun(a); //with it and without it will be different
}
}

int main(){
Array b;

for(int i=0; i<3; i++)
for(int j=0; j<3; j++){
b.n[j] = i+j;
}

fun(b);
}
******************************************************************************

ah HAH!
I was assuming that Array had object semantics, not value semantics...

Now, if you change
void fun(Array a)
to
void fun(Array &a)

You will see that calling fun(a) makes no difference.
 
C

cplusplusquestion

How do you figure? Without knowing how "Array" is defined, it is not
possible for us to tell whether the call to fun(a) serves any useful
purpose or not. For example, one could imagine a more complete program
fragment - and one for which it is clear that the call to fun(a) is
useful:
    const int MAX1 = 16;
    const int MAX2 = 32;
    typedef int (&Array)[MAX1][MAX2];
    void fun(Array a)
    {
        for (int i = 0; i < MAX1; i++)
            for (int j = 0; j < MAX2; j++)
                if (a[j] != -1)
                {
                    calculateSomeValue(a[j]);
                    a[j] = -1;
                    fun(a);
                }
    }
Greg

Here is my example code:
********************************************************************************
#include <iostream>
using namespace std;
struct Array{
   int n[3][3];
};
void fun(Array a)
{
   for (int i = 0; i < 3; i++)
   for (int j = 0; j < 3; j++)
           if (a.n[j] != -1)
           {
//                 calculateSomeValue(a[j]);
                   cout << i << " " << j << " " << a.n[j] << endl;
                   a.n[j] = -1;
                   fun(a);   //with it and without it will be different
           }
}

int main(){
   Array b;
   for(int i=0; i<3; i++)
           for(int j=0; j<3; j++){
                   b.n[j] = i+j;
           }

   fun(b);
}
******************************************************************************

ah HAH!
I was assuming that Array had object semantics, not value semantics...

Now, if you change
void fun(Array a)
to
void fun(Array &a)

You will see that calling fun(a) makes no difference.


passing with value and passing with reference, the result is different.
 
D

Daniel Pitts

How do you figure? Without knowing how "Array" is defined, it is not
possible for us to tell whether the call to fun(a) serves any useful
purpose or not. For example, one could imagine a more complete program
fragment - and one for which it is clear that the call to fun(a) is
useful:
const int MAX1 = 16;
const int MAX2 = 32;
typedef int (&Array)[MAX1][MAX2];
void fun(Array a)
{
for (int i = 0; i < MAX1; i++)
for (int j = 0; j < MAX2; j++)
if (a[j] != -1)
{
calculateSomeValue(a[j]);
a[j] = -1;
fun(a);
}
}
Greg
Here is my example code:
********************************************************************************
#include <iostream>
using namespace std;
struct Array{
int n[3][3];
};
void fun(Array a)
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (a.n[j] != -1)
{
// calculateSomeValue(a[j]);
cout << i << " " << j << " " << a.n[j] << endl;
a.n[j] = -1;
fun(a); //with it and without it will be different
}
}
int main(){
Array b;
for(int i=0; i<3; i++)
for(int j=0; j<3; j++){
b.n[j] = i+j;
}
fun(b);
}
******************************************************************************

ah HAH!
I was assuming that Array had object semantics, not value semantics...

Now, if you change
void fun(Array a)
to
void fun(Array &a)

You will see that calling fun(a) makes no difference.


passing with value and passing with reference, the result is different.

Yes, but is the "passing with reference" result "wrong"?

If it isn't, then you can pass by reference and then remove the recursion.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top