Solved

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

Posted on 2004-10-09
12
180 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
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 

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 500 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

Are your AD admin tools letting you down?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
C++ assignment question 7 199
C++ standard library based binary archive format 6 98
IdTCPClient1->Disconnect(); not working 3 67
Which Linux flavors will this run on? 6 88
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…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

803 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