Advertisemen
An old programming practical was to compute the mean, median and mode of an array in C, I wanted to convert this to C++ using vectors and templates:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
template <class Ty> struct frequencyTracker; //structure for tracking the mode
template <class Ty> vector<Ty> getVectorFromArray(const Ty *arr, int numElements); //converts a given array into a vector
template <class Ty> Ty* getArrayFromVector(const vector<Ty> *vec); //converts a given vector into an array
template <class Ty> Ty compareValues(const void *x,const void *y); //comparison function for the quick sort
template <class Ty> void qsortVector( vector<Ty> *toSort ); //quicksorts a vector
template <class Ty> double getMean(const vector<Ty> *values); //gets the mean of the given values
template <class Ty> double getMedian(const vector<Ty> *values); //gets the median of the given values
template <class Ty> Ty getMode(const vector<Ty> *values); //gets the mode of the given values
int main()
{
int arr[] = {2,2,9,5,6,5,3,5,6};
vector<int> values = getVectorFromArray<int>(arr,9);
cout << "Mean: " << getMean(&values) << endl;
cout << "Median: " << getMedian(&values) << endl;
cout << "Mode: " << getMode(&values) << endl;
return 0;
}
template <class Ty> struct frequencyTracker
{
Ty value;
int count;
};
template <class Ty> Ty compareValues ( const void *x, const void *y )
{
//comparison function
Ty dx,dy;
dx = *(Ty*)x;
dy = *(Ty*)y;
lass="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0cm; mso-layout-grid-align: none; text-autospace: none;"> if (dx < dy) return -1;
else if (dx > dy) return 1;
else return 0;
}
template <class Ty> void qsortVector( vector<Ty> *toSort )
{
Ty *vectorArr = new Ty[toSort->size()]; //create array
for (vector<Ty>::size_type i = 0; i < toSort->size(); i++)
vectorArr[i] = (*toSort)[i]; //push all values into array
qsort(vectorArr,toSort->size(),sizeof(Ty),&compareValues); //sort array
for (vector<Ty>::size_type i = 0; i < toSort->size(); i++)
(*toSort)[i] = vectorArr[i]; //push array values into vector
delete[] vectorArr; //clearup mem
}
template <class Ty> vector<Ty> getVectorFromArray(const Ty *arr, int numElements)
{
vector<Ty> conversionVector;
for (int i=0;i<numElements;i++)
conversionVector.push_back(arr[i]);
return conversionVector;
}
template <class Ty> Ty* getArrayFromVector(const vector<Ty> *vec)
{
Ty *conversionArray = new Ty[vec->size()]; //allocate memory
int a = vec->size();
for (int i = 0; i < vec->size(); i++)
conversionArray[i] = (*vec)[i];
return conversionArray;
}
template <class Ty> double getMean(const vector<Ty> *values)
{
double mean = 0;
for (vector<Ty>::size_type i=0;i<values->size();i++) //sum
mean+=(*values)[i];
return mean/values->size();
}
template <class Ty> double getMedian(const vector<Ty> *values)
{
//quicksort the array
vector<Ty> sortedArray;
for (int i=0;i<values->size();i++)
sortedArray.push_back((*values)[i]);
qsortVector(&sortedArray);
//get the median
if ((values->size()/2)*2 == values->size()) //if num elements is even
return static_cast<double>(sortedArray[values->size()/2-1]+sortedArray[values->size()/2])/2; //return average of the middle values
else return sortedArray[(values->size()-1)/2]; //return n+1 element
}
template <class Ty> Ty getMode(const vector<Ty> *values)
{
//quicksort the array
vector<Ty> sortedArray;
for (int i=0;i<values->size();i++)
sortedArray.push_back((*values)[i]);
qsortVector(&sortedArray);
//get the mode
frequencyTracker<Ty> MaxValue;
frequencyTracker<Ty> CurrentValue;
MaxValue.count = 0;
MaxValue.value = 0;
CurrentValue.count = 0;
CurrentValue.value = 0;
for (
int j=0;
j<values->size();
j++)
{
if (!!j) //if not first element ( i != 0 )
if (sortedArray[j] == sortedArray[j-1])
CurrentValue.count++;
else //new value, reset counters
{
if (CurrentValue.count > MaxValue.count) //new max freq found
MaxValue = CurrentValue;
//reset current value
CurrentValue.count = 1;
CurrentValue.value = sortedArray[j];
}
else
{
CurrentValue.count = 1;
CurrentValue.value = sortedArray[j];
}
}
//one last check for the final element
if (CurrentValue.count > MaxValue.count) //new max freq found
MaxValue = CurrentValue;
//delete[] sortedArray;
return MaxValue.value;
}
Advertisemen
Tidak ada komentar:
Posting Komentar