Two Dimensional Arrays

I am stuck on completing one of my functions, which consists of a two dimensional array that has to calculate the average for each column. I have tried switching NUM_MOVIES and NUM_REVIEWERS for each for loop and that does not work.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

const int NUM_REVIEWERS = 4;   //Number of rows in reviews array
const int NUM_MOVIES = 6;      //Number of columns in reviews array

 double showAverageRatings(const int array[][NUM_MOVIES])
{
    int average = 0, sum = 0;

    for(int row = 0; row <  NUM_REVIEWERS; row++)
    {
        for(int col = 0; col < NUM_MOVIES; col++)
        {
            sum = sum + array[row][col];
            cout << sum << endl; // temporally display values for test.
        }
        average = sum / NUM_MOVIES;
    }
    return average;
}
Last edited on
> that has to calculate the average for each column.
That would suggest you need an array, but you're only returning one value.

> showAverageRatings
What's in a name?
'show' suggests printing rather than returning.
But you do return a value.

You also made average an int, but you're returning a double.


Perhaps
1
2
void calculateAverageRatings(const int array[][NUM_MOVIES], double averages[NUM_MOVIES]) {
}
Your right "calculateAverageRatings" would be more of an accurate name in regards to what the function actually does. Thanks for pointing out that average was an int. I have corrected it to a double like it should be. That was a silly mistake on my part. It is the algorithm for getting the average for each column that I am trying to fix.
I second @salem c's point that you are only returning one value - if you want an average for each column then you will have to have an array for them (or use an extra row of the existing array).

But consider where you set sum = 0;
If you want an average for each column then you should set it to 0 before summing over that column. At present you set it to 0 once only before doing anything.

And if you genuinely want to average over each column ... then the columns loop should be the OUTER one. Even if you fixed where you set sum to 0, then you would at present be averaging a row, not a column.
Last edited on
I am not clear on what you mean by, "if you want an average for each column then you will have to have an array for them (or use an extra row of the existing array)."

I currently have an array set up and I am trying to iterate over that to get the average. Are you suggesting that I need a new array in addition to this to make it work?

I have posted only the function and the declarations that fill the array, but if it is more helpful, then I can post the whole program.

I have updated to try and match what you said and it still is not correct.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
double calculateAverageRatings(const int array[][NUM_MOVIES])
{
    int sum = 0;
    double average = 0;

    for(int col = 0; col < NUM_MOVIES; col++)
    {   sum = 0;
        for(int row = 0; row <  NUM_REVIEWERS; row++)
        {
            sum = sum + array[col][row];
            cout << sum << endl; // temporally display values for test.
        }
        average = sum / NUM_MOVIES;
    }
    return average;
}
@stonejax

(1) What SINGLE value do you wish to return? Because at the moment you are only returning ONE value. Yet you say that you want the average of each column, and there are NUM_MOVIES (i.e. 6) or them.

(2) If you sum over NUM_REVIEWERS (which seems reasonable) then you should be dividing by NUM_REVIEWERS on line 13. At present you are dividing by NUM_MOVIES.

(3) sum is an int. NUM_MOVIES is an int. Therefore, sum / NUM_MOVIES (or even the more correct sum / NUM_REVIEWERS) will be done by integer division at line 13 (giving a wrong answer), irrespective of whether average is defined as double or not.

(4) Why don't you cout << average; between your current lines 13 and 14.

(5) Yes, we had best see the whole code.



I am not clear on what you mean by, "if you want an average for each column then you will have to have an array for them (or use an extra row of the existing array)."
Please explain what you don't understand there.

Last edited on
Thanks for pointing out to reset the counter.

I got it to work with the cout statement inside the function, but the last averaged value prints 30 and it should be 3. Also, if I omit the cout statement and use the return statement instead, then I will only get a single value of 3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
double calculateAverageRatings(const int array[][NUM_MOVIES])
{
    int sum = 0;
    double average = 0;

    for(int col = 0; col < NUM_MOVIES; col++)
    {   sum = 0;

        for(int row = 0; row <  NUM_REVIEWERS; row++)
        {
            sum = sum + array[row][col];
           // cout << sum << endl; // temporally display values for test.
            average = sum / NUM_MOVIES;

        }
        average = sum / 4.0;
        cout << endl;
        cout << "Movie#" << col + 100 << ": " << average;
    }
    //return average;
}
@stonejax,
Please READ what I wrote. The last version is worse than before.
stoneJax, practice time.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;

const int REVIEWERS = 3;
const int MOVIES = 5;
void foo ( int arr[REVIEWERS][MOVIES] ) {
    for ( int col = 0 ; col < MOVIES ; col++ ) {
        int sum = 0;
        for ( int row = 0 ; row < REVIEWERS ; row++ ) {
            sum += arr[row][col];
        }
        cout << "Col " << col << " sums to " << sum << endl;
    }
}

int main()
{
    int arr[REVIEWERS][MOVIES] = {
        { 1, 2, 3, 4, 5 },
        { 10, 20, 30, 40, 50 },
        { 100, 200, 300, 400, 500 },
    };
    foo(arr);
  return 0;
}


Now experiment with
1
2
3
    for ( int row = 0 ; row < REVIEWERS ; row++ ) {
        int sum = 0;
        for ( int col = 0 ; col < MOVIES ; col++ ) {


When you get stuck, put your code to one side and create a really simple test case of the problem at hand.
@ lastchance, sorry I missed your last two posts last night.

I am assuming that you said the last code is worse than it was before because it is supposed to be a value returning function, and instead of returning it's using cout. Shows lack of understanding the concepts. I am seeing that now.

In reference to:
"(stoneJax) I am not clear on what you mean by, "(lastchance) if you want an average for each column then you will have to have an array for them (or use an extra row of the existing array)."
(lastchance) Please explain what you don't understand there."

I am new so I really have no idea where you are going with that statement. It sounds like you are saying to create another array to hold the new values or wipe out existing values in the same array to hold them, but I am not sure. If so, that is beyond the scope of what I have practiced.

I Took to Salem's approach today and turned the function into a void function and now it works perfectly. I'll post it below.

Although the function works and I am happy with it the way it is, I still want to learn why it didn't work as a return function. I am in a first course C++ class so the material is new and I am trying to solidify the information into memory and get consistent.

It seems that I am off on understanding exactly how to use a return function for this scenario. Lastchance asks "What SINGLE value do you wish to return?" Here, maybe this is the problem because I am not trying to return a single value but rather, an average for each column. Here is a posted example output.
1
2
3
4
5
6
7
Average Rating for each movie:
Movie#100: 3.75
Movie#101: 1.25
Movie#102: 3
Movie#103: 3
Movie#104: 2.75
Movie#105: 3 


Here is my new code as a void function that works good.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void calculateAverageRatings(const int array[][NUM_MOVIES])
{
    int sum = 0;
    double average = 0;

    for(int col = 0; col < NUM_MOVIES; col++)
    {   sum = 0;

        for(int row = 0; row <  NUM_REVIEWERS; row++)
        {
            sum = sum + array[row][col];
            average = sum / NUM_MOVIES;
        }
        average = sum / 4.0;
        cout << endl;
        cout << "Movie#" << col + 100 << ": " << average;
    }
    cout << endl;
}





Last edited on
In your most recent code you aren't "returning" anything - either through the value of the function on return, or through one of its arguments. You are merely printing it out.

Your line 12 is still wrong in about as many ways as it can be. It is in the wrong place: you should complete the summing of the column (ie finish all the internal loops); it is doing integer division (and so would give a truncated answer); it is dividing by NUM_MOVIES rather than NUM_REVIEWERS.

Fortunately in this instance, line 12 is superseded by a re-calculation of the average on line 14 before you print anything out. However, that will only work if the number of reviewers is 4: it will be wrong for any other number.

Finally, I don't see why you arbitrarily add 100 in line 16.

These aren't errors associated with C++. They are fundamental errors of logic that would occur whatever language you used.
I decided to leave it as a void function so I am aware that it is not returning anything. I was just carrying on the conversation of a return function to learn more.

Thanks for pointing out line 12. I got it to work with line 14 and forgot to delete it.
Also, for this program the number of reviewers is fixed as:
const int NUM_REVIEWERS = 4;
. . . so all I need is 4.

On line 16, the "col + 100" refers to a movie number. For example, when col = 0, then 0 + 100 displays "Movie# 100."

I appreciate you guys taking the time to look at my code!
If you are going to hard-code 4 at that position in the code, then there would be little point in having a variable NUM_REVIEWERS at all, since it won't work if NUM_REVIEWERS was ever changed. If you look back at @salem c's example you will see that he actually used 3 in that instance.

If you put global constants named like that at the top of your code then any user will expect the code to automatically respond correctly to any other values that they may be changed to. As it is, your code will only ever work if NUM_REVIEWERS is 4, which is very restrictive and not implied by the way you write those constants.
That makes sense for a program that is in real life. This program is a passing class assignment and the stage is set for the students and the students finalize it. So certain things like const int NUM_REVEIWERS = 4 were already set for us. IDK why they don't teach it in a less restrictive manner like you say.
Topic archived. No new replies allowed.