views:

213

answers:

2

I'm having a problem with a template ARRAY class. I have another Rational class that i added to this ARRAY class. what i need it to do is take in rational numbers as fractions (exp 1/2) and sort them. i believe i need to overload the relational operators but thats where im stuck. do i over load them in the ARRAY class or the Rational Class. below is my code

//generic.cpp
using namespace std;

template<class T>
void Quicksort (T& a, int first, int last);

template<class T>
int split (T& a, int first, int last);

template<class T>
void change (T& e1, T& e2); 

template<class T>
void Mergesort(T& a, int first, int last);

template<class T>
void Merge(T& a, int first, int last);

int main()  
{
    int num;

    Rational r1;

    cout << "\nHow many rationals? ";
    cin >> num;
    Array<Rational> r2(num);
    cout << "Enter the " << num << " rationals below:\n";
    for (int i=0; i<num ; i++)  
        cin >> r2[i];
    cout << "\nThank you!!\n";
    cout << "Initially, the rationals are\n"
         <<  " r2 = " << r2 << "\n";

    // Copy the original array and sort it using Quicksort
    Array<Rational> r3(r2);
    Quicksort(r3, 0, num-1);
    cout << "\nElements sorted using quicksort:\n";
    for (int i=0; i<num ; i++)  
        cout << r3[i]<< " ";
    cout << "\n";

// Print original list of elements.
cout << "\nOriginal elements:\n";
    for (int i=0; i<num ; i++)  
        cout << r2[i]<< " ";
    cout << "\n";

    // Copy original array and sort it using MergeSort
    Array<Rational> r4(r2);
    Mergesort(cm, 0, num-1);
    cout << "\nElements sorted using mergesort:\n";
    for (int i=0; i<num ; i++)  
        cout << r4[i]<< " ";
    cout << "\n";

    return 0;
}

template<class T>
int split (T& a, int first, int last) 
{
    T::value_type pivot =  a[first]; 
    int left = first;
    int right = last;
    while (left<right)
    {
        while (pivot < a[right])  //search from right for <=pivot
            right--;
            while (left<right &&(a[left]<pivot || a[left]==pivot)) 
                left++;
            if (left<right)
                change(a[left],a[right]);
    }
    int pivotPosition = right;
    a[first] = a[pivotPosition];
    a[pivotPosition] = pivot;
    return pivotPosition;
}

template<class T>
void Quicksort (T& a, int first, int last)
{
    int pos;
    if (first < last)
    {
        pos=split(a,first,last);
        Quicksort(a,first,pos); //sort lsft sublist
        Quicksort(a,pos+1,last); //sort right sublist
    }
}

template<class T>
void change (T& e1, T& e2) 
{
    T tmp = e1; 
    e1 = e2; 
    e2 = tmp;
}

template<class T>
void Mergesort(T& a, int first, int last) 
{
    if (first < last) 
    {
        int mid = (first + last) / 2;
        Mergesort(a, first, mid);
        Mergesort(a, mid+1, last);
        Merge(a, first, last);
    }
}

template<class T>
void Merge(T& a, int first, int last) 
{
    int mid = (first + last) / 2;
    int one = 0, two = first, three = mid + 1;
    Array<T::value_type> temp(a.get_size());

    while (two <= mid && three <= last) // Neither sublist is done
        if (a[two] < a[three])          // Value in first half is smaller
           temp[one++] = a[two++];
        else                            // Value in second half is smaller
           temp[one++] = a[three++];
    while (two <= mid)                  // Finish copying first half
           temp[one++] = a[two++];
while (three <= last)               // Finish copying second half
           temp[one++] = a[three++];
    for (one = 0, two = first; two <= last; a[two++] = temp[one++]);
}

.

//ARRAY.h

using namespace std;

template<class T> class Array 
{
public:
    typedef T value_type;
    Array(int s);
    Array(int l, int h);

    Array(const Array& other);
    ~Array();

    T& operator[](int index);
    const T& operator[](int index) const;

    int get_size() const {return arraySize;}

private:
    int low;
    int high;
    int arraySize; //size of array
    int offset; //to adjust back to an index of zero
    T *array_;

    void Copy(const Array&);
};

.

//rational.cpp
using namespace std;

Rational::Rational()
{
    num = 0;
    den = 1;
}

Rational::Rational(int n, int d)
{
    if (d==0){
       cout << "Error: division by zero." << endl;
       exit(1);
    }
    num = n;
    den = d;
    simplify();
}

Rational& Rational::operator+=(const Rational& r)
{
    num = (num * r.den) + (den * r.num);
    den = den * r.den;
    simplify();
    return *this;
}

Rational& Rational::operator-=(const Rational& r)
{
    num = (num * r.den) - (den * r.num);
    den = den * r.den;
    simplify();
    return *this;
}

Rational& Rational::operator*=(const Rational& r)
{
    num *= r.num;
    den *= r.den;
    simplify();
    return *this;
}

Rational& Rational::operator/=(const Rational& r)
{
    if (r.num == 0) {
       cout << "Error: division by zero." << endl;
       exit(1);
    }
    num *= r.den;
    den *= r.num;
    simplify();
    return *this;
}

const Rational& Rational::operator= (const Rational& rightObj)
{
    if (this != &rightObj)
    {
       num = rightObj.num;
       den = rightObj.den;
    }
    return *this;
}

const Rational Rational::operator-() const
{
    Rational answer(-num, den);
    return answer;
}

const Rational operator+(const Rational& q, const Rational& r)
{
    Rational answer = q ;
    answer += r ;
    return answer;
}

const Rational operator-(const Rational& q, const Rational& r)
{
    Rational answer = q ;
    answer -= r ;
    return answer;
}

const Rational operator*(const Rational& q, const Rational& r)
{
    Rational answer = q ;
    answer *= r ;
    return answer;
}

const Rational operator/(const Rational& q, const Rational& r)
{
    Rational answer = q ;
    answer /= r ;
    return answer;
}

istream& operator>>(istream& in, Rational& r)
{
    char ch;
    in >> r.num >> ch >> r.den;
    r.simplify();
    return in;
}

ostream& operator<<(ostream& out, const Rational& r)
{
    if (r.den == 1)
    {
        out << r.num;
    }else
    {
        out << r.num << "/" << r.den;
    }
    return out;
}

.

//rational.h

using namespace std;

class Rational
{
    friend ostream& operator<< (ostream&, const Rational&);
    friend istream& operator>> (istream&, Rational&);

 public:
    Rational();
    Rational(int, int);

    double value() const;
    Rational reciprocal() const;

    Rational& operator+=(const Rational&);
    Rational& operator-=(const Rational&);
    Rational& operator*=(const Rational&);
    Rational& operator/=(const Rational&);

    const Rational& operator= (const Rational&);

    const Rational operator-() const;

private:
    int num;
    int den;
    void simplify();
};

const Rational operator+(const Rational&, const Rational&);
const Rational operator-(const Rational&, const Rational&);
const Rational operator*(const Rational&, const Rational&);
const Rational operator/(const Rational&, const Rational&);
+3  A: 

If you are trying to compare two or more objects of class rational then the relational operators should be methods or friends of class rational. If you need to compare two or more objects of class array then the relational operators should be methods or friends of class array.

Patrick
A: 

You overload them in the Rational class, if you're sorting using the < operator:

bool operator < (const Rational& rhs) const {  // rhs = right hand side
    // return true if 'this' less than 'rhs'
}

or

bool operator < (const Rational&lhs, const Rational& rhs) {
    // return true if 'lhs' less than 'rhs'
}

if you choose to not use a member function

/A.B.

Andreas Brinck