Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

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

Posted on 2004-10-09
12
Medium Priority
?
188 Views
Last Modified: 2010-04-01
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
Comment
Question by:dinorama
  • 6
  • 6
12 Comments
 
LVL 19

Expert Comment

by:mrwad99
ID: 12271395
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
 

Author Comment

by:dinorama
ID: 12273134
what is T***  ?? and T*** arr ?
0
 
LVL 19

Expert Comment

by:mrwad99
ID: 12274262
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:dinorama
ID: 12293021
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
 

Author Comment

by:dinorama
ID: 12301390
help plz ??
0
 
LVL 19

Expert Comment

by:mrwad99
ID: 12301956
You need to do what I said; pass the address of your char** to the function taking a char***.  It has to work !
0
 

Author Comment

by:dinorama
ID: 12303871
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
 

Author Comment

by:dinorama
ID: 12303886
now <HELP PLZ!!!>
0
 
LVL 19

Accepted Solution

by:
mrwad99 earned 2000 total points
ID: 12307221
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
 
LVL 19

Expert Comment

by:mrwad99
ID: 12307244
...and if this help I have given is not worthy of an overall 'A' grade, I don't know what is....;-)
0
 

Author Comment

by:dinorama
ID: 12313873
Great! now it works! thanks <mrwad99>. I really appreciate your help!

thank you.
0
 
LVL 19

Expert Comment

by:mrwad99
ID: 12316511
Glad to help.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

885 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question