Link to home
Start Free TrialLog in
Avatar of kiyosanim
kiyosanim

asked on

Comparing generic data records based on priority

Hi experts.  I am working with  2 classes for building generic data records.  The Records have a vector of Fields and the Fields have a name, type, and value.  Anyway I have overloaded the comparison operators in order to compare two records. Now I need the opertaors to  compare two records based on priority keys that are set before the comparison.  For instance, compare last name, first name, middle initial in order. Priorities are set using SetPriority(name, value). Whats the best way to implement comparison of records based on these priorities?

#include <iostream>
#include <cstdlib>

#include <iostream>
#include <vector>

using std::vector;
using std::cout;
using std::endl;

#define INT_TYPE       100
#define REAL_TYPE      101
#define STR_TYPE       102

class Field {
  public:
    Field(const char *, const int);
    Field(const char *, const double);
    Field(const char *, const char*);
    ~Field();
    Field(const Field&);
    const char  *GetName() const { return name; }
      const char  *GetName(const char *) const { return name; }
      
    int GetType() const          { return type; }
    int GetSize() const          { return size; }
    const char * GetTypeStr() const;
    void Set(const int val)      { intVal  = val; }
    void Set(const double val)   { realVal = val; }
    void Set(const char *val)    { CopyString(val, &strVal); }
    const int    GetInt() const  { return intVal; }
    const double GetReal() const { return realVal; }
    const char  *GetStr() const  { return strVal; }
      
      bool operator==(const Field & rhs) const;
      bool operator!=(const Field & rhs) const;
      bool operator<(const Field & rhs) const;
      bool operator>(const Field & rhs) const;
   
      const int GetPriority() const { return priority; }
    void SetPriority(int val)    { priority = val; }

  private:
    char *name;
    int type;
    int size;
    int intVal;
    double realVal;
    char *strVal;

    int priority;

    void SetName(const char *);
    void CopyString(const char *, char **);
};


Field::Field(const char *fName, int val)
   : type(INT_TYPE), realVal(0.0), strVal(NULL), priority(0)
{
  SetName(fName);
  size = static_cast<int>(sizeof(int));
  intVal = val;  
}


Field::Field(const char *fName, double val)
   : type(REAL_TYPE), intVal(0), strVal(NULL), priority(0)
{
  SetName(fName);
  size = static_cast<int>(sizeof(double));
  realVal = val;  
}


Field::Field(const char *fName, const char *val)
   : type(STR_TYPE), intVal(0), realVal(0.0), priority(0)
{
  SetName(fName);
  size = static_cast<int>(strlen(val) + 1);
  CopyString(val, &strVal);
}


Field::Field(const Field &rhs)
   : type(rhs.type), intVal(rhs.intVal), realVal(rhs.realVal),
     size(rhs.size), priority(rhs.priority)
{
    SetName(rhs.name);
    if (type != STR_TYPE)
       strVal = NULL;
    else
       CopyString(rhs.strVal, &strVal);
}


Field::~Field()
{
   delete [] name;
   if (strVal)
      delete [] strVal;  
}    


void Field::SetName(const char *fName)
{
    CopyString(fName, &name);
}

void Field::CopyString(const char *srcP, char **tgtPP)
{
  *tgtPP = new char[static_cast<int>(strlen(srcP))+1];
  strcpy(*tgtPP, srcP);
}


const char * Field::GetTypeStr() const
{
    if (type == INT_TYPE)
       return "INT ";
    else if (type == REAL_TYPE)
       return "REAL";
    else if (type == STR_TYPE)
       return "CHAR";
    else
       return "UNKOWN";
}
bool Field ::operator==(const Field & rhs) const
{
      if (type != rhs.type) return false;
      if (size!= rhs.size) return false;
        if (strcmp(name, rhs.name)) return false;
        if (realVal)
        {
        if (realVal != rhs.realVal) return false;
        }
        if (intVal)
        {
        if (intVal != rhs.intVal)return false;
        }
     
        if (strVal)
        {
      if (strcmp(strVal, rhs.strVal)) return false;
        }
      return true;
}

bool Field ::operator!=(const Field & rhs) const
{
      if (type != rhs.type) return true;
      if (size!= rhs.size) return true;
        if (strcmp(name, rhs.name)) return true;
      
        if (realVal)
        {
        
              if (realVal != rhs.realVal)
             
                    return true;
        }
        if (intVal)
        {
        
              if (intVal != rhs.intVal)
             
                    return true;
        }
     
        if (strVal)
        {
     
              if (strcmp(strVal, rhs.strVal))
             
                    return true;
        }
     
        return false;
}

bool Field ::operator<(const Field & rhs) const
{
      if (type != rhs.type) cout << " //throw exception; Field ::operator< #1 " << endl;
      if (size!= rhs.size) cout << "//throw exception; Field ::operator< #2" << endl;
      if (strcmp(name, rhs.name)) cout << "//throw exception; Field ::operator< #3" << endl;
      
        if (realVal)
        {
        
              if (realVal < rhs.realVal)
             
                    return true;
        }
        if (intVal)
        {
        
              if (intVal < rhs.intVal)
             
                    return true;
        }
     
        if (strVal)
        {
     
              if (strcmp(strVal, rhs.strVal)< 0)
             
                    return true;
        }
     
        return false;
}

bool Field ::operator>(const Field & rhs) const
{
      if (type != rhs.type) cout << "//throw exception; Field ::operator> #1 " << endl;
      if (size!= rhs.size) cout << "//throw exception; Field ::operator> #2" << endl;
      if (strcmp(name, rhs.name)) cout << "//throw exception; Field ::operator> #3" << endl;
      
        if (realVal)
        {
        
              if (realVal > rhs.realVal)
             
                    return true;
        }
        if (intVal)
        {
        
              if (intVal > rhs.intVal)
             
                    return true;
        }
     
        if (strVal)
        {
     
              if (strcmp(strVal, rhs.strVal)> 0)
             
                    return true;
        }
     
        return false;
}

class Record
{
  public:
    Record() { }
    void AddField(const char*, int);
    void AddField(const char*, double);
    void AddField(const char*, const char *);
    void Print() const;
    void SetPriority(const char *, int);
    int GetPriority(const char *) const;
      bool operator==(const Record& rhs) const;
      bool operator<(const Record& rhs) const;
      bool operator>(const Record& rhs) const;
   
  private:
    vector<Field> fields;
      int * keys;
};

void Record::AddField(const char *name, int val)
{
    fields.push_back(Field(name, val));
}

void Record::AddField(const char *name, double val)
{
    fields.push_back(Field(name, val));
}

void Record::AddField(const char *name, const char *val)
{
    fields.push_back(Field(name, val));
}

void Record::Print() const
{
   int i;

   for (i=0; i < static_cast<int>(fields.size()); i++) {
      cout << fields[i].GetName() << ": " 
           << fields[i].GetTypeStr() << " " << fields[i].GetSize() << " "
           << " pri: " << fields[i].GetPriority() << " value: ";
      if (fields[i].GetType()==INT_TYPE)
         cout << fields[i].GetInt();
      else if (fields[i].GetType()==REAL_TYPE)
         cout << fields[i].GetReal();
      else cout << fields[i].GetStr();
          cout << endl;

   }
   cout << endl;      
}


void Record::SetPriority(const char *fName, int val)
{
   int i;
   for (i=0; i< static_cast<int>(fields.size()); i++)
      if (!strcmp(fName, fields[i].GetName()))
         break;
   if (i < static_cast<int>(fields.size()))
        fields[i].SetPriority(val);  // Should verify val >= 0
      
}
int  Record::GetPriority(const char * fName) const
{
      int i;
      for (i=0; i< static_cast<int>(fields.size()); ++i)
      {
         if (!strcmp(fName, fields[i].GetName()))
        
              return fields[i].GetPriority();
      }       

      return -1;
}

        
bool Record::operator==(const Record& rhs) const
{
      if (fields.size() != rhs.fields.size())
              return false;

      for(int i = 0;i < static_cast<int> (fields.size()); i++)
      {
           if (fields[i] != rhs.fields[i])
                  return false;
      }
      return true;
}

bool Record::operator<(const Record& rhs) const
{
        if (fields.size() != rhs.fields.size())
              cout << " throw exception in Record::operator< #1 " << endl;

      for(int i = 0;i < static_cast<int> (fields.size()); i++)
      {
           if (fields[i] < rhs.fields[i])
                  return true;
      }
      return false;
}

bool Record::operator>(const Record& rhs) const
{
            if (fields.size() != rhs.fields.size())
            {
              cout << " throw exception in Record::operator> #2 " << endl;
            }
            
      


      for(int i = 0;i < static_cast<int> (fields.size()); i++)
      {
           if (fields[i] > rhs.fields[i])
                  return true;
      }
      return false;
}

int main()
{
    Record r1, r2, r3;

   r1.AddField("first name", "John");
   r1.AddField("last name", "Jones");
   r1.AddField("middle initial", "P");
   r1.AddField("age", 30);
   r1.AddField("student id", 102030);
   r1.AddField("street address", "250 Belmont Ridge");
   r1.AddField("city", "Columbus");
   r1.AddField("state", "OH");
   r1.AddField("zipcode", "55223");
   

 
   r1.Print();

   
  r2.AddField("first name", "Jackie");
   r2.AddField("last name", "Smith");
   r2.AddField("middle initial", "L");
   r2.AddField("age", 29);
   r2.AddField("student id", 111223);
   r2.AddField("street address", "512 Elm St");
   r2.AddField("city", "New York");
   r2.AddField("state", "NY");
   r2.AddField("zipcode", "12345");



   r2.Print();
   
   cout << endl;
   cout << endl;


   if (r1 == r2)
   {
         cout << "THEY ARE EQUAL!!" << endl;
   }
   else
   {
         cout << "NOT EQUAL!!" << endl;
   }

   if (r1 < r2)
   {
         cout << "r1 < r2!!" << endl;
   }
   else
   {
         cout << "r1 >= r2!!" << endl;
   }
   
        
if (r1 > r2)
   {
         cout << "r1 > r2!!" << endl;
   }
   else
   {
         cout << "r1 <= r2!!" << endl;
   }
   
   cout << endl;
   cout << endl;


      
   system("pause");
   return 0;
}
ASKER CERTIFIED SOLUTION
Avatar of grg99
grg99

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial