Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 196
  • Last Modified:

{{Question: in C++ using dynamic arrays; pointer + function templates etc }}

hey dudez,

I just got this question that i am working on. I just got stuck at the *maximum* and *minimum* functions. I just having difficulty in writing out the functions for them.

Here is the question:
-----------------------------------------------------------------------------------------------------------------
Design a program which uses a two-dimensional dynamic array to store the values of temperature and humidity for different days. The array should be dimensioned as [2]*[noDays], where the number of days noDays is specified by the user at run-time. The program should do the following:
       •      get the number of days from the user
      •      allocate a 2-D array dynamically
      •      get the values of temperature and humidity for each day from the user
            and store these values into the two rows of the array
      •      compute and display the average value of each row (i.e. the average
                        temperature and humidity)
      •      compute and display the maximum and minimum value of each row
            
 
It is required to design and use the three function templates that compute and return the average, maximum and minimum value respectively.  
--------------------------------------------------------------------------------------------------------------------------
Here is my code:

#include <iostream>
#include <stdlib.h>
#include<conio.h>
using namespace std;
int noDays; //global variable for the no of days entered
template<typename any> //average func template
any average (any total)
{
      any total_ave;
      total_ave = total/noDays;
      return total_ave;
}
template<typename any1> //maximum value func template HAVING PROBLEMS WITH THIS FUNC!
/*any1 maximum (any1 arr[0][noDays])
{
      int i,temp;
      for(i=0; i<noDays; i++) {
            if(arr[0][i]<arr[0][i+1])
                  temp = arr[0][i+1];
            else if(arr[1][i]<arr[1][i+1])
                  temp = arr[1][i+1];
               
      }
      return temp;
}*/
/*template<typename any2> //minimum value func template  HAVING PROBLEMS WITH THIS FUNC
any2 minimum (any2 arr[2][noDays])
{
      int i, temp;
      for(i=0; i<noDays; i++) {
            if(arr[0][i]<arr[0][i+1])
                  temp= arr[0][i];
            else if (arr[1][i]<arr[1][i+1])
                  temp= arr[1][i];
      }
      return temp;
}*/
int main() // main function --------------
{
      float **ptr;
      int i,j;
      float total1=0, total2=0;
      cout<<"Enter number of days: "<<endl;
      cin>>noDays;
      ptr = new float*[2];
      if(!ptr)
      {
            cout<<"Memory error";
            exit(1);
      }
      for(i=0; i<2; i++)
      {
            ptr[i] = new float [noDays];
            if (!ptr) {
                  cout<<"Memory error";
                  exit(1);
            }
      }
      cout<<"Enter the temperature values for "<<noDays<<" days:"<<endl;
      for(int j=0; j<noDays;j++)
      {
            cin>>ptr[0][j];
            total1 = total1 + ptr[0][j];
      }
      cout<<endl;
      cout<<"Enter the humidity values for "<<noDays<<" days:"<<endl;
      for(int k=0; k<noDays; k++)
      {
            cin>>ptr[1][k];
            total2= total2 + ptr[1][k];
      }
      cout<<"The average temperature is: "<< average(total1)<<endl;
      cout<<endl;
      cout<<"The average humidity is: "<<average(total2)<<endl;
      cout<<endl;
      getch();
}

tHANKS.
dino.

0
dinorama
Asked:
dinorama
  • 6
  • 6
1 Solution
 
mrwad99Commented:
Your use of templates is questionable; I suggest that you re-read on how they are used after solving this.

Your minimum function needs to take a pointer to your 2D array, and the row that you wish to find the minimum value for (row 0 = temperature, row 1 = humidity according to how you build the array in main() ).  Hence

template <class T> T minimum(T*** arr, int nIndex)

Then you need to check every element against every other one, to make sure you get the lowest value.  I would set the lowest value to be the first element in the row you are looking at, then compare every other one with that.  

template <class T> T minimum(T*** arr, int nIndex)
{
      T min = (*arr)[nIndex][0];


Then it is just a case of looping through the other elements, comparing and adjusting min if necessary:

template <class T> T minimum(T*** arr, int nIndex)
{
      T min = (*arr)[nIndex][0];

      for (int i = 1; i < noDays; i++) {
            if ( (*arr)[nIndex][i] < min)
                  min = (*arr)[nIndex][i];
      }
      return min;
      
}

With

float **ptr;

You could call this like

float f = minimum<float>(&ptr, 0);
cout << "Minimum is " << setprecision(4) << f << endl; // Round to 4 Sf


It should be easy to figure out how to do a function giving the maximum hence...

Regarding your average it would be much better to pass the array into it, rather than pass a sum of the array's values only to do a basic division in the function...


HTH
0
 
dinoramaAuthor Commented:
what is T***  ?? and T*** arr ?
0
 
mrwad99Commented:
Since you have allocated memory for a 2D array on the heap, you need to pass a pointer to this; i.e. a pointer to (a pointer to a pointer).  Since your pointer to pointer is of type float, you will have a pointer to a pointer to a pointer that is of type float, i.e. float***.  Now I have used T*** in the template function header since the point of templates is to allow types of any kind; in this case the type is specified by the generic parameter T.

When you compile this code, the compiler will see you are trying to use the function minimum with floats, from the statement

float f = minimum<float>(&ptr, 0);

hence the function will become

template <class float> float minimum(float*** arr, int nIndex)
{
     float min = (*arr)[nIndex][0];

     for (int i = 1; i < noDays; i++) {
          if ( (*arr)[nIndex][i] < min)
               min = (*arr)[nIndex][i];
     }
     return min;    
}

This is the essence of using templates.

You could call minimum with any other type, eg minimum<int>(..), but then the first parameter would have to be of this type(**) also; i.e.

int n = minimum<int>(&ptr, 0);

would fail since ptr is of type float** and the template is expecting an int**.  So when the template is completed at compile time, it looks like

template <class int> float minimum(int*** arr, int nIndex)
//...

...so of course you cannot pass the address of a float** as the first parameter.

Finally; why do I pass &ptr not ptr ?  Well in the latter, the first parameter of minimum would change to T**, but this would mean copying the array which is inefficient.  Since I pass the address, I need the extra level of pointer in the template argument, hence T***

I hope this clarifies.
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

 
dinoramaAuthor Commented:
ok. <mrwad99 >. I have tried it. But, it says, "Could find a match for 'minimum <flaot> (float ***, int)' ". Well, it was obvious as the first argument is different than the argument in the function. Like when i call minimum from the main.

so, what to do now?? can i creat a pointer which would point to **ptr ?? possible?

thanks
0
 
dinoramaAuthor Commented:
help plz ??
0
 
mrwad99Commented:
You need to do what I said; pass the address of your char** to the function taking a char***.  It has to work !
0
 
dinoramaAuthor Commented:
ok. this is what i wrote:

float min = minimum(&ptr, 0);
    cout<<"The minimum value of tempertaure is: "<<min;

then, it gave me that error.

ok.. lemme post my whole code here:
---------------------------------------------------------------------------------------------------------------

#include <iostream>
#include <stdlib.h>
#include<conio.h>

using namespace std;
int noDays; //global variable for the no of days entered

template<typename any> //average func template
any average (any total)
{
      any total_ave;
      total_ave = total/noDays;
      return total_ave;
      
}

template <class flaot>

float minimum(float*** arr, int nIndex)
{
     float min = (*arr)[nIndex][0];

     for (int i = 1; i < noDays; i++) {
          if ( (*arr)[nIndex][i] < min)
               min = (*arr)[nIndex][i];
     }
     return min;
}


int main() // main function --------------
{
      float **ptr;
 int i,j;
float total1=0, total2=0, min;
      cout<<"Enter number of days: "<<endl;
      cin>>noDays;
      ptr = new float*[2];
      if(!ptr) {
            cout<<"Memory error";
            exit(1);
      }
      for(i=0; i<2; i++)
      {
            ptr[i] = new float [noDays];
            if (!ptr) {
                  cout<<"Memory error";
                  exit(1);
            }
      }
      cout<<"Enter the temperature values for "<<noDays<<" days:"<<endl;
      for(int j=0; j<noDays;j++){
            cin>>ptr[0][j];
            total1 = total1 + ptr[0][j]; }
      cout<<endl;
      cout<<"Enter the humidity values for "<<noDays<<" days:"<<endl;
      for(int k=0; k<noDays; k++) {
            cin>>ptr[1][k];
            total2= total2 + ptr[1][k]; }
            
   
    cout<<"The average temperature is: "<< average(total1)<<endl;
    cout<<endl;
    cout<<"The average humidity is: "<<average(total2)<<endl;
    cout<<endl;

    min = minimum(&ptr, 0);
    cout<<"The minimum value of tempertaure is: "<<min;
-----------------------------------------------------------------------------------------------------------------
0
 
dinoramaAuthor Commented:
now <HELP PLZ!!!>
0
 
mrwad99Commented:
Firstly, we are apparently in different timezones since your postings differ in time by around 10 hours, so that is why I don't give instant responses; *I am not ignoring you !*

Right, I am afaid that you have misunderstood some things about templates, and would recommend re-reading about them.  I will however try and explain as best I can.

When you define a template function, eg

template<class T> T minimum(T***, int nIndex)

you are telling the compiler to substitute the template parameter, in this case T, with whatever the function is called with.  So if you instantiated this function with floats, as in

float f = minimum<float>(..,..)

you are stating that you are calling this function in the context of floats.  So, *what the compiler will do* is substitute all the template parameters in your template function with 'float', so our minimum function becomes

template<class float> float minimum(float***, int nIndex)

as far as the compiler is concerned.

*You don't type this, this is what the compiler generates !*

You were apparently confused by this, as was your compiler, when you coded

template <class flaot> float minimum(.......)

To start with, the compiler has no idea what a flaot is (I presume this is a typo) so would assume that flaot is the name you have chosen for the template parameter ('T' in my example above).  In the function body, you don't reference flaot again, so this function is in essence only dealing with floats; not a template function hence !

You need the following function in your code

template <class T> T minimum(T*** arr, int nIndex)
{
     T min = (*arr)[nIndex][0];

     for (int i = 1; i < noDays; i++) {
          if ( (*arr)[nIndex][i] < min)
               min = (*arr)[nIndex][i];
     }
     return min;
     
}

So this should work overall:

#include <iostream>
#include <stdlib.h>
#include<conio.h>

using namespace std;
int noDays; //global variable for the no of days entered

template<typename any> //average func template
any average (any total)
{
     any total_ave;
     total_ave = total/noDays;
     return total_ave;
     
}


template <class T> T minimum(T*** arr, int nIndex)
{
     T min = (*arr)[nIndex][0];

     for (int i = 1; i < noDays; i++) {
          if ( (*arr)[nIndex][i] < min)
               min = (*arr)[nIndex][i];
     }
     return min;
     
}

int main() // main function --------------
{
     float **ptr;
 int i,j;
float total1=0, total2=0, min;
     cout<<"Enter number of days: "<<endl;
     cin>>noDays;
     ptr = new float*[2];
     if(!ptr) {
          cout<<"Memory error";
          exit(1);
     }
     for(i=0; i<2; i++)
     {
          ptr[i] = new float [noDays];
          if (!ptr) {
               cout<<"Memory error";
               exit(1);
          }
     }
     cout<<"Enter the temperature values for "<<noDays<<" days:"<<endl;
     for(int j=0; j<noDays;j++){
          cin>>ptr[0][j];
          total1 = total1 + ptr[0][j]; }
     cout<<endl;
     cout<<"Enter the humidity values for "<<noDays<<" days:"<<endl;
     for(int k=0; k<noDays; k++) {
          cin>>ptr[1][k];
          total2= total2 + ptr[1][k]; }
         
   
    cout<<"The average temperature is: "<< average(total1)<<endl;
    cout<<endl;
    cout<<"The average humidity is: "<<average(total2)<<endl;
    cout<<endl;

    min = minimum<float>(&ptr, 0);
    cout<<"The minimum value of tempertaure is: "<<min;
}

I hope this helps.
0
 
mrwad99Commented:
...and if this help I have given is not worthy of an overall 'A' grade, I don't know what is....;-)
0
 
dinoramaAuthor Commented:
Great! now it works! thanks <mrwad99>. I really appreciate your help!

thank you.
0
 
mrwad99Commented:
Glad to help.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 6
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now