C++ comparing variables as an object - c++

I'm trying to compare two variables and the type of these variables are "Time". I can't seem to use the == / != function for these.
#include<iostream>
#include "Stock.h"
using namespace std;
void Stock::setShares(int d, int m, int y, int h, int mts, double p, int vol, double val)
{
date.setDate(d, m, y);
time.setTime(h, mts);
price = p;
value = val;
volume = vol;
}
Date Stock::getDate() const
{
return date;
}
Time Stock::getTime() const
{
return time;
}
This is in my main program:
Time t1, t2;
for (int i = 1; i < counter; ++i)
{
if (V1.at(i).getPrice() == highestPrice)
{
time2 = V1.at(i).getTime;
if (time2 != time1)
{
cout << time2;
}
}
}
How can I compare time1 & time2? I'm trying to avoid printing duplicate values of time in my program. V1 is a vector loaded with data from Stock object.

Check first whether == or != operator is overloaded for type Time. You must provide your own meaning to operators which you are gonna to use in your code for user-defined types else you will get compiler errors.
something like below,
class Time
{
public:
bool operator==(Time const & t1) const
{
return this.hour == t1.hour && this.min==t1.min;
}
private:
int min;
int hour;
};

In order to be able to answer your question completely, it would be necessary to know the details of the type "Time". Since you talk about comparing two objects, let's assume it is class.
If it was simple class like this:
class Time {
public:
int getValue();
void setValue(int value);
private:
int value;
}
You would need to use getValue method:
if( t1.getValue() == t2.getValue())
If you want to compare the objects directly, you need to overload the necessary operators:
bool operator==(const Time& anotherTime) const {
return (anotherTime.getValue()==this->getValue());
}

Related

Kattis annoyed coworkers problem (self-sorting data structures and a min heap )

Okay so am trying to make a data structure that maintains a heap of data in order to solve within the compile-time limit. https://open.kattis.com/problems/annoyedcoworkers
I might be in over my head since I just started coding in the last year or so and I just learned about sorting and vectors last week and heap data structures yesterday. But I am really interested in solving this problem.
Anyway here goes I first started to solve this problem with selection sort... needless to say it took way too long.
Then I started looking into making a heap data structure that yields values sorted order,
which brought me to priority_queue
After about 9 hours of trying different methods, this is the closest I've gotten to solving the problem.
does anyone have any suggestions as to why after 25/27 test cases my code returns a wrong answer?
Here is my code :
// C++ program to use priority_queue to implement Min Heap
// for user defined class
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
// User defined class, coworker
class CoworkerT
{
private:
int a;
int d;
public:
CoworkerT(int _a, int _d)
{
a = _a;
d = _d;
}
int SimAddAD() const
{
int aD;
aD = a + d;
return aD;
}
int AddAD()
{
a = a + d;
return a;
}
int getA() const {
return a;
}
int getD() const {
return d;
}
};
// To compare two coworkers possible a value
class Min
{
public:
int operator() (const CoworkerT& p1, const CoworkerT& p2)
{
return p1.SimAddAD() > p2.SimAddAD();
}
};
//compare two a values between coworkers
class Max
{
public:
int operator() (const CoworkerT& p1, const CoworkerT& p2)
{
return p1.getA() < p2.getA();
}
};
int AskForA() {
int a;
cin >> a;
return a;
}
int AskForD() {
int d;
cin >> d;
return d;
}
priority_queue <CoworkerT, vector<CoworkerT>, Max >
PopulateMax(priority_queue <CoworkerT, vector<CoworkerT>, Max > max,
priority_queue <CoworkerT, vector<CoworkerT>, Min > min) {
while (min.empty() == false)
{
CoworkerT e = min.top();
max.push(CoworkerT(e.getA(), e.getD()));
min.pop();
}
return max;
}
// Driver code
int main()
{
int h, c, i, a, d;
cin >> h >> c;
// Creates a Min heap of points (order by possible a +d combination )
priority_queue <CoworkerT, vector<CoworkerT>, Min > pq;
// Creates a Max heap of points (order by actual a value )
priority_queue <CoworkerT, vector<CoworkerT>, Max > max;
// Insert points into the min heap
for (int i = 0; i < c; i++) {
a = AskForA();
d = AskForD();
pq.push(CoworkerT(a, d));
}
i = 0;
while (i < h) {
CoworkerT e = pq.top();
a = e.AddAD();
d = e.getD();
pq.pop();
pq.push(CoworkerT(a, d));
i++;
}
max = PopulateMax(max, pq);
CoworkerT eMax = max.top();
cout << eMax.getA() << endl;
return 0;
}
I just want to say that I ended up using something similar to my original algorithm using the heap. The problem was my use of int I switched to an unsigned long long int ~(though that might have been overkill?) and it worked like a charm.
// C++ program to use priority_queue to implement Min Heap
// for user defined class
#include <algorithm>
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
// User defined class, coworker
class CoworkerT {
private:
unsigned long long int a;
unsigned long long int d;
public:
CoworkerT(unsigned long long int _a, unsigned long long int _d){
a = _a;
d = _d;
}
unsigned long long int SimAddAD() const{
return a + d;
}
unsigned long long int AddAD(){
return a + d;;
}
unsigned long long int getA() const {
return a;
}
unsigned long long int getD() const {
return d;
}
};
//compare two coworkers possible a + d values
struct MinSort {
bool operator()(const CoworkerT& p1, const CoworkerT& p2) const {
return p1.SimAddAD() < p2.SimAddAD();
}
};
//compare two coworkers possible a + d values ~for some reason heap lesser than or greater need to be reverse of operator for sort???
struct Min {
bool operator()(const CoworkerT& p1, const CoworkerT& p2) const {
return p1.SimAddAD() > p2.SimAddAD();
}
};
//compare two a values between coworkers
struct MaxSort {
bool operator()(const CoworkerT& p1, const CoworkerT& p2) const {
return p1.getA() > p2.getA();
}
};
void FindAndPrintMax(vector<CoworkerT>& max) {
sort(max.begin(), max.end(), MaxSort());
CoworkerT minMax = max.front();
cout << minMax.getA();
}
void InputCoworkersAD(vector<CoworkerT>& min, unsigned long long int& h, unsigned long long int& c) {
int a, d, i;
cin >> h >> c;
// Insert a and d into the vector
if (h <= 100000 && h >= 1 && c <= 100000 && c >= 1) {
for (i = 0; i < c; i++) {
cin >> a >> d;
min.push_back(CoworkerT(a, d));
}
}
make_heap(min.begin(), min.end(), Min());
}
void AskForHelp(vector<CoworkerT>& min, unsigned long long int h) {
int i = 0;
while (i < h) {
push_heap(min.begin(), min.end(), Min());
CoworkerT e = min.front();
pop_heap(min.begin(), min.end(), Min());
min.pop_back();
min.push_back(CoworkerT(e.AddAD(), e.getD()));
i++;
}
}
// Driver code
int main()
{
unsigned long long int h, c;
vector<CoworkerT> min;
InputCoworkersAD(min, h, c);
AskForHelp(min, h);
FindAndPrintMax(min);
return 0;
}

Why am I getting a Link error when I try to overload an operator?

I'm doing a project exercise, where I'm revising a previous project of a class I created called Polynomial to use a link list (the original used arrays). The link list uses a template so that any type can be passed into it.
One of the problems I ran into with this project exercise is that I am trying to pass an object of type PolyNumber (from a class I made), and the link list bag I made has a function that compares any item (using ==) that is passed to it.
It works fine with regular types, such as int and string, but runs into problems with custom made object types. So I figured out how to overload the == operator in the PolyNumber class. By itself, it works when I test this class, but when I use this type with the Polynomial class with the Link List implementation, I get errors such as the following for each method in the Polynomial class:
Error LNK2005 "public: __thiscall PolyNumber::PolyNumber(int,int)" (??0PolyNumber##QAE#HH#Z) already defined in Polynomial.obj Project11
Here's my code for those files, but as you can see in the code, there are other files that go with this code, such as the LinkedBag for the link list object, but for space I just include these:
PolyNumber.h
#pragma once
class PolyNumber
{
public:
PolyNumber();
PolyNumber(int set_coefficent, int set_degree);
void setDegree(int set);
void setCoefficient(int set);
int getDegree();
int getCoefficient();
friend bool operator== (const PolyNumber& p1, const PolyNumber& p2);
friend bool operator!= (const PolyNumber& p1, const PolyNumber& p2);
private:
int degree;
int coefficient;
};
PolyNumber.cpp
#include "PolyNumber.h"
PolyNumber::PolyNumber()
{
coefficient = 0;
degree = 0;
}
PolyNumber::PolyNumber(int set_coefficent, int set_degree)
{
coefficient = set_coefficent;
degree = set_degree;
}
void PolyNumber::setDegree(int set)
{
degree = set;
}
void PolyNumber::setCoefficient(int set)
{
coefficient = set;
}
inline int PolyNumber::getDegree()
{
return degree;
}
inline int PolyNumber::getCoefficient()
{
return coefficient;
}
bool operator== (const PolyNumber& p1, const PolyNumber& p2)
{
return (p1.coefficient == p2.coefficient && p1.degree == p2.degree);
}
bool operator!= (const PolyNumber& p1, const PolyNumber& p2)
{
return !(p1 == p2);
}
Polynomial.h
#pragma once
#include "PolynomialInterface.h"
#include "LinkedBag.cpp"
#include "PolyNumber.cpp"
static const int POLYNOMIAL_SIZE = 10;
class Polynomial : public Polynomoal_Interface
{
public:
//Cunstructs am empty Polynomial
Polynomial();
//Copy constructor
Polynomial(Polynomial& copy);
/** Cunstructs a Polynomial with a client defined Polynomial
#param an array of non-negative integer coeffient that does not exceed POLYNOMIAL_SIZE, each coeffient in the array has a power that correspounds
to the respective value of the location of the ceffient in that array. */
Polynomial(int coeffient[POLYNOMIAL_SIZE], int size);
int degree();
int coefficient(int power);
bool changeCoefficient(int newCoefficient, int power);
private:
//static const int POLYNOMIAL_SIZE = 10;
//int polynomial[POLYNOMIAL_SIZE];
LinkedBag<PolyNumber> bag;
};
Polynomial.cpp
#include "Polynomial.h"
Polynomial::Polynomial()
{
}
Polynomial::Polynomial(Polynomial& copy)
{
std::vector<PolyNumber> copyFrom = copy.bag.toVector();
for (int i = 0; i < copyFrom.size(); i++)
{
bag.add(copyFrom[i]);
}
}
Polynomial::Polynomial(int coeffient[POLYNOMIAL_SIZE], int size)
{
for (int i = 0; i <= size; i++)
{
PolyNumber number = { coeffient[i], i + 1 };
bag.add(number);
}
}
int Polynomial::degree()
{
int max = 0;
std::vector<PolyNumber> result = bag.toVector();
for (int i = 0; i < result.size(); i++)
{
if (result[i].getDegree() > max)
{
max = result[i].getDegree();
}
}
return max;
}
int Polynomial::coefficient(int power)
{
int result = 0;
std::vector<PolyNumber> powerOf = bag.toVector();
for (int i = 0; i < powerOf.size(); i++)
{
if (powerOf[i].getDegree() == power)
{
result = powerOf[i].getCoefficient();
}
}
return result;
}
bool Polynomial::changeCoefficient(int newCoefficient, int power)
{
PolyNumber number = { newCoefficient, power };
int result = coefficient(power) + newCoefficient;
bag.remove(number);
number.setCoefficient(result);
bag.add(number);
return true;
}
You have #include "PolyNumber.cpp" instead of #include "PolyNumber.h".
That makes all the methods defined in PolyNumber.cpp to be included (and re-defined) in Polynomial.cpp.
The same will happen with LinkedBag.
Why are you including cpps?

Accessing data members of an object from a list

So BCD is a list of objects of another class BankCustomerDetails. BCD is also a data member of a class BankSystem.
Let's say I want to access the second customer's name from the list, something like this:-
BCD[1].Name
But this is not working.
class BankSystem
{
private:
std::list<BankCustomerDetails>BCD;
public:
std::list<BankCustomerDetails> GetBankCustomerDetails();
void SetBankCustomerDetails(std::list<BankCustomerDetails>&);
int GetTotalCustomerCount();
void Create_AddCustomerAccount_BankSystem(BankCustomerDetails&);
bool SearchCustomerDetails_byName(std::string);
bool SearchCustomerDetails_byAccountNumber(unsigned long int);
void UpdateCustomerDetails_byAccountNumber(std::string ,unsigned long int );
void DepositMoney_byAccountNumber(unsigned long int ,double);
void WithdrawMoney_byAccountNumber(unsigned long int , double);
double BalanceInquiryofCustomer_byAccountNumber(unsigned long int );
void DeleteCustomerDetails_byAccountNumber(unsigned long int );
void DisplayAllCustomerDetails();
};
class BankCustomerDetails
{
private:
std::string Name;
unsigned long int Account_Number;
double Account_Balance;
public:
BankCustomerDetails();
BankCustomerDetails(std::string, unsigned long in, double);
std::string GetBankCustomerName();
unsigned long int GetBankCustomerAccount_Number();
double GetBankCustomerAccount_Balance();
void SetBankCustomerName(std::string&);
void SetBankCustomerAccount_Number(unsigned long int&);
void SetBankCustomerAccount_Balance(double&);
void AcceptBankCustomerDetails();
void DisplayBankCustomerDetails();
};
And This is What i want to do:-
At Client.cpp
string nm;
BankSystem BS;
cout<<"Enter The Customer Name to Search Details"<<endl;
cin>>nm;
int flag = BS.SearchCustomerDetails_byName(nm);
At BankSystem.cpp
bool BankSystem::SearchCustomerDetails_byName(std::string name)
{
//Need to Implement
for(int i = 0; i < BCD.size(); i++){
if(BCDName = name)
return true;
}
return false;
}
You cannot access std::list elements with an index and square brackets. I recommend using a std::vector instead of a std::list. Then you can write:
for (int i = 0; i < BCD.size(); i++) {
if (BCD[i].GetBankCustomerName() == name) {
return true;
}
}
Of course you could also do the same thing with a list but then you have to rewrite the loop using an iterator.
std::list<BankCustomerDetails>::iterator iterator;
for (iterator = intList.begin(); iterator != intList.end(); ++iterator)
if (iterator->GetBankCustomerName() == name) {
return true;
}
}
Still I recommend using the vector because it almost always has better performance.
Two more notes:
List itemBCD[i].Name does not work because Nameis private.
The comparison operator is == and not =.

Returning a class object based on two variables C++

I need help with a problem pertaining to classes. I know how to solve it but I am wondering if there is a better solution than my current idea.
Each Class Tile Object and Class Player Object has an x and y position. I would like to know if there is a way to expedite things. My current idea is if-else statements like this:
if(x==1) {
if(y==1) {
return tileone1;
} else if(y==2) {
return tileone2;
} else if(y==3) {
return tileone3;
} else if(y==4) {
return tileone4;
} else if(y==5) {
return tileone5;
} //......
} else if(x==2) {
if(y==1) {
return tiletwo1;
} else if(y==2) {
return tiletwo2;
} else if(y==3) {
return tiletwo3;
} else if(y==4) {
return tiletwo4;
} else if(y==5) {
return tiletwo5;
} //......
} //......
The problem is it would take way too long to write this for every tile.
I need a function that will return a Tile object based on the x and y input of the Object Player. Any other solution would be great as well.
Tile getTileBasedOnCoords(int x, int y){
}
There are multiple ways to achieve this. The easiest seems to be (given the question) is by putting all Tile objects into the array, and returning the one with corresponding index.
Use a map with custom keys providing x and y values. This way you have direct access to the tile without the need to compare each tile with the player position (see getSectorByCoordinate() in the following code taken from a project of mine).
struct CSectorCoordinate
{
private:
int mX;
int mY;
public:
CSectorCoordinate();
CSectorCoordinate(int aX, int aY);
bool operator() (const CSectorCoordinate & a, const CSectorCoordinate & b) const;
int getX();
int getY();
};
...
bool CSectorCoordinate::operator() (const CSectorCoordinate & a, const CSectorCoordinate & b) const
{
// note: the following conditions ensure a strict weak ordering (see documentation of std::map)
if (a.mX < b.mX)
return true;
if (b.mX < a.mX)
return false;
return a.mY < b.mY;
}
...
typedef std::map<CSectorCoordinate, Configuration::CSectorEntity *, CSectorCoordinate> CSectorCoordinateMap;
CSectorCoordinateMap mSectorCoordinateMap;
...
bool CSectorEntityConfigurationBunch::getSectorByCoordinate(int aX, int aY, Configuration::CSectorEntity * & prSector)
{
CSectorCoordinateMap::const_iterator i(mSectorCoordinateMap.find(CSectorCoordinate(aX, aY)));
if (i != mSectorCoordinateMap.end())
prSector = i->second;
else
prSector = 0;
return prSector;
}

How to compare two objects (the calling object and the parameter) in a class?

I am writing a "Date" class for an assignment and I am having trouble doing one the of the functions.
This is the header file for the class.
class Date
{
public:
Date(); // Constructor without parameters
Date(int m, int d, int y); // Constructor with parameters.
// accessors
int GetMonth(); // returns the size of the diamond
int GetDay();
int GetYear();
// mutators
bool Set(int m, int d, int y);
bool SetFormat(char f);
// standard input and output routines
void Input();
void Show();
void Increment(int numDays = 1);
int Compare(const Date& d);
private:
int month, // month variables
day, // day variable
year; // year variable
char format;
};
The member function I am trying to make is the int Compare(const Date& d) function. I need this function to compare two Date objects (the calling object and the
parameter), and should return: -1 if the calling object comes first
chronologically, 0 if the objects are the same date, and 1 if the parameter object
comes first chronologically.
I have tried doing a simple if statement with the == operator but I get errors.
if (d1 == d2)
cout << "The dates are the same";
return (0);
After the objects are created, the function should be called like this d1.Compare(d2)
Thank you in advance!
int Date :: Compare (const Date& d) {
if (year<d.year) {
return -1;
}
else if (year>d.year) {
return 1;
}
else if (month<d.month) {
return -1;
}
else if (month>d.month) {
return 1;
}
// same for day
return 0;
}
Usually, you'lll also want to provide overloaded comparison operators, for example (also within the class definition):
bool operator == (const Date& d) const {
return !Compare(d);
}
bool operator < (const Date& d) const {
return Compare(d)<0;
}
... // consider using boost::operators
PS: There are smarter implementations of Compare() - just check the other answers. This one is pretty straightforward and readable, but conforms exactly to your specification.
into the class's public area
bool operator==(const Date& rhs) const {
return
year == rhs.year
&& month == rhs.month
&& day == rhs.day
;
}
Here's how I might implement your Compare function, although the format takes a moment to get used to:
int Date::Compare(const Date& d) const {
return
(year < d.year) ? -1 :
(year > d.year) ? 1 :
(month < d.month) ? -1 :
(month > d.month) ? 1 :
(day < d.day) ? -1 :
(day > d.day) ? 1 :
0;
}
Or perhaps:
template<typename T>
int Compare(T a, T b) {
if (a < b) return -1;
if (b < a) return 1;
return 0;
}
int Date::Compare(const Date& d) const {
int a = Compare(year, d.year);
if (a == 0) a = Compare(month, d.month);
if (a == 0) a = Compare(day, d.day);
return a;
}
I wouldn't use operator== in Compare, although the answers telling you how to implement operator== are fine if you want that as well. The reason is that operator== is clearly going to have to look at the same fields compare does, and if it returns false then Compare will do very similar work again. Efficiency probably isn't an issue, but it duplicates the logic.
And for what it's worth, idiomatic C++ is to implement operator< and possibly also a consistent operator== and operator>, rather than an all-in-one Compare function. The operators are what the standard algorithms use for searching and sorting, and everything else follows. Java chose to do things differently.
Compare object by contents, i.e. in your case the dates are equal of the day, month and year are equal (and perhaps format - depending on your semantics).
Also, C++ already includes a great facility for object comparison: operator == which allows writing clearer code than calling a Compare method.
By the way, take care with this:
if (d1 == d2)
cout << "The dates are the same";
return (0);
If the condition is true, the cout line will be executed. The return will be executed even if the condition is false.
The semantics of C++'s || make this a little cluttered:
static inline int cmp(int a, int b)
{
return a < b ? -1 : a == b ? 0 : 1;
}
int Date::Compare(const Date& d)
{
int result;
(result = cmp(year, d.year)) ||
(result = cmp(month, d.month)) ||
(result = cmp(day, d.day));
return result;
}
In order to use operator== for user-defined types, you must implement it. In addition, your Compare function should be marked as a const member function:
class Date
{
...
int Compare(const Date& d) const;
bool operator==(const Date& rhs) const
{
return 0 == Compare(rhs);
}
You can't do d1 === d2, because I believe it compares the memory addresses (haven't done C++ in a while).
What you need to do is write a function that will compare each member of your Date class and return negative number, 0, or positive number. Negative means lesser, 0 means the same, and positive means greater.
For example, in Java:
public int compareTo(Date date) {
int returnValue = 0;
returnValue = this.getYear() - date.getYear();
if(returnValue == 0) {
returnValue = this.getMonth() - date.getMonth();
if(returnValue == 0) {
returnValue = this.getDay() - date.getDay();
}
}
}
class Temp {
public:
Temp(const char* str) {
this->str = str;
printf("Temp [%s] is created\n", this->str);
}
~Temp() {
printf("Temp [%s] is deleted\n", this->str);
}
bool operator == (const Temp& a) const {
return this->str == a.str;
}
private:
const char* str = new char[10];
}
int main() {
Temp test1{"Hello1"};
Temp test2{"Hello2"};
(test1 == test2) ? printf("Equals") : printf("Non equals");
return 0;
}