Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Comparing generic data records based on priority

Posted on 2005-04-18
1
Medium Priority
?
232 Views
Last Modified: 2010-04-01
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;
}
0
Comment
Question by:kiyosanim
1 Comment
 
LVL 22

Accepted Solution

by:
grg99 earned 1500 total points
ID: 13809132
You could keep an array of function pointers, let's say you can live with TEN priority levels:

FuncPtr CompareTab[10];

.. .then just call the functions from first to last (skip NULL ones).

If the function returns Zero, go on and call the next one,
if it returns non-zero, that's the one that makes the decision, you don't have to compare any further.

0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

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…
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
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.

581 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