I am attempting to implement a operator>() function using only the <, || and ! operators. I can do so using the == oparator, but I cannot figure out how to eliminate the case of one operand being equal to the other using only the three given operators. Here is how I have done it otherwise:
bool operator>(a, b){
if(!(a < b) || !(a == b){
return true;
}
else{
return false;
}
}
So far the only possibility I have come up with that may work would be to somehow create a recursive function. Other than that, is there any other way in which this can be done?
a < b if and only if b > a - as #Kerrek put it so simply above.
bool operator>(a, b){
if(b < a){
return true;
}
else{
return false;
}
}
EDIT: Or even to further simplify, thanks to #Mokosha below
bool operator>(a, b){
return b < a;
}
Besides the obvious solution proposed by #KerrekSB (which is the best because of its simplicity), just as a curiosity you can also follow this approach from your code using the XNOR operator (note that it's not possible to do it using only the || operator, because for defining XOR you need both the || and the && operators - more here):
bool operator>(a, b){
if(!(a < b) || !(x ^ y){
return true;
}
else{
return false;
}
}
Related
If I am enclosing the code after first if upto second return in curly braces it is not giving me desired output.
static int comparator(Player a, Player b) {
if(a.score == b.score)
if(a.name == b.name)
return 0;
else
return (a.name > b.name)? -1:1;
return (a.score < b.score)? -1:1;
}
Your code has if() and else statements. Each will execute one line of code that comes after them. This means that it will only execute a single statement and end after the first ; that it finds.
for() loops, while() loops, if-else blocks can be used without curly braces if the statement you want to execute consists of only one line of code following them.
Your code works as -
static int comparator(Player a, Player b) {
// if statement without braces- means just one statement executes
if(a.score == b.score)
// Remember if-else will be considered as a single code block so both will run
if(a.name == b.name)
return 0;
else
return (a.name > b.name)? -1:1;
// This statement will run only when the above if condition is not satisfied
return (a.score < b.score)? -1:1;
}
This can be considered to be same as -
static int comparator(Player a, Player b) {
if(a.score == b.score) {
if(a.name == b.name) {
return 0;
} else {
return (a.name > b.name) ? -1 : 1;
}
}
return (a.score < b.score) ? -1 : 1;
}
NOTE : It is generally better if you use the braces as it will be good for readability as well as maintainability of the code. There can actually be two way of parsing it - Dangling else(though most compiler will associate the else with closest if).
In this coding style, there's no way to differentiate between below two code -
if(condition1)
if(condition2)
foo1();
else
foo2();
and,
if(condition1)
if(condition2)
foo1();
else
foo2();
Since, in C/C++, it doesn't consider the indentation in code, so it might create ambiguity while reading the code. So its always better to use curly braces instead of doing it like above. Drop them only when you have a single line and it won't create any confusion reading the code later on...
Hope this helps !
Without curly braces, only the next statement is executed. With proper indentation it becomes easier to see what's going on:
static int comparator(Player a, Player b) {
if(a.score == b.score)
if(a.name == b.name)
return 0;
else
return (a.name > b.name) ? -1 : 1;
return (a.score < b.score) ? -1 : 1;
}
This is actually the same as:
static int comparator(Player a, Player b) {
if(a.score == b.score) {
if(a.name == b.name) {
return 0;
} else {
return (a.name > b.name) ? -1 : 1;
}
}
return (a.score < b.score) ? -1 : 1;
}
You have maybe used the braceless else variant without noticing it when writing something like:
if(condition) {
//
} else if(another_condition) {
//
} else {
//
}
Which is actually the same as
if(condition) {
//
} else {
if(another_condition) {
//
} else {
//
}
}
Without curly braces, the if guard only applies to the immediate next statement.
It's just how the language works. :/
So I was tinkering with || and && operators with return. I developed an understanding by comparing int as for example return 1 || 0; return 0 || 0; that the program returns 1 or 0 in case of an int function and true or false in case of bool functions after comparing values.
Now I was writing a code to find path sum to given value using implementation of trees.
bool HasPathSum(ds::sn::BNode<int>* root, int value)
{
if (!root && !value)
{
return true;
}
else if(root)
{
return HasPathSum(root->left, value - root->data)
|| HasPathSum(root->right, value - root->data);
}
return false;
}
I managed to write it after massive tinkering. For recursion I was doing
HasPathSum(root->left, value - root->data);
return HasPathSum(root->right, value - root->data);
To explore all the paths, but it wasn't quite all right because if the path sum was in left, It did go to true but eventually returned false. I figured I will have to write the recursive definition in a single line for it to work and wrote || just as an experiment and it blew my mind that it actually worked. I wrote std::cout << value << " "; at the top of if statement to see what is happening and it does what its supposed do and stops just as a path has been found.
This is all that I've tried but I am unable too wrap my head around how the recursive function with || works or will work if given &&.
If someone experienced can provide an explanation! :)
operator || and operator && does short circuit, so might doesn't evaluate second operand depending of the first one.
bool b = f() || g(); is mostly equivalent to
bool b = f();
if (b == false) b = g();
bool b = f() && g(); is mostly equivalent to
bool b = f();
if (b == true) b = g();
struct Something {
union {
float k;
int n;
};
bool isFloat;
bool operator==(const Something& mS)
{
if(isFloat != mS.isFloat) return false;
if(isFloat && mS.k == k) return true;
if(!isFloat && mS.n == n) return true;
}
};
My implementation of Something::operator== seems rather expensive and convoluted. Is this the only way to check equality in classes with union types?
Or is there a better way that avoids branches/checking additional variables?
bool operator==(const Something& mS)
{
if (isFloat != mS.isFloat)
{
return false;
}
else if (isFloat)
{
return mS.k == k;
}
else
{
return mS.n == n;
}
}
Clear and debuggable with the minimum number of checks. You want to have a constructor and/or set methods to ensure isFloat is correct at all times.
You can remove one redundant check, and perhaps enhance readability slightly, by replacing the last two lines with
if(isFloat != mS.isFloat) return false; // As you have
return isFloat ? mS.k == k : mS.n == n;
(or the equivalent if construct, as in Sean Perry's answer) but the compiler will probably do just as good a job of optimising your version.
There's no way to avoid a runtime check that the types match. You might consider a ready-made discriminated union type like Boost.Variant; it won't be any more efficient, but it might be easier and less error-prone to use.
return (isFloat && mS.isFloat && k==mS.k) || (!isFloat && !mS.isFloat && n==mS.n);
I do not think that you can escape checking all the conditions. So the question can be how to write them more simpler and expressively.
I would write them the following way
bool operator==( const Something &mS ) const
{
return ( ( isFloat == mS.isFloat ) && ( isFloat ? k == mS.k : n == mS.n ) );
}
Sorry if this is a stupid question, but it's something that I'm curious about.
I am overloading the less-than operator for my sort algorithm based on last name, first name, middle name. I realize there is not a right or wrong here, but I'm curious as to which style is written better or preferred among fellow programmers.
bool CPerson::operator<(const CPerson& key) const
{
if (m_Last < key.m_Last)
|| ( (m_Last == key.m_Last) && (m_First < key.m_First) )
|| ( (m_Last == key.m_Last) && (m_First == key.m_First) && (m_Middle < key.m_Middle) )
return true;
return false;
}
or
bool CPerson::operator<(const CPerson& key) const
{
if (m_Last < key.m_Last)
return true;
else if ( (m_Last == key.m_Last) && (m_First < key.m_First) )
return true;
else if ( (m_Last == key.m_Last) && (m_First == key.m_First) && (m_Middle < key.m_Middle) )
return true;
else
return false;
}
or
bool CPerson::operator<(const CPerson& key) const
{
if (m_Last < key.m_Last)
return true;
if (m_Last == key.m_Last)
if (m_First < key.m_First)
return true;
if (m_Last == key.m_Last)
if (m_First == key.m_First)
if (m_Middle < key.m_Middle)
return true;
return false;
}
I prefer:
bool CPerson::operator<(const CPerson& key) const
{
if (m_Last == key.m_Last) {
if (m_First == key.m_First) {
return m_Middle < key.m_Middle;
}
return m_First < key.m_First;
}
return m_Last < key.mLast;
}
Nice and systematic, and it is obvious how new members can be added.
Because these are strings, the repeated comparison may be needlessly inefficient. Following David Hamman's suggestion, here is a version which only does the comparisons once per string (at most):
bool CPerson::operator<(const CPerson& key) const
{
int last(m_Last.compare(key.m_Last));
if (last == 0) {
int first(m_First.compare(key.m_First));
if (first == 0) {
return m_Middle < key.m_Middle;
}
return first < 0;
}
return last < 0;
}
All of your implementations are essentially the same and they are all wrong by any reasonable definition of sort order for people's names. Your algorithm will place Jonathan Abbott Zyzzyk ahead of Jonathan Zuriel Aaron.
What you want is person A's name is less than person B's name if:
The last name of person A is less than the last name of person B or
The two have the same last name and
The first name of person A is less than the first name of person B or
The two have the same first name and the middle name of person A is less than the middle name of person B.
Whether you implement this as a single boolean expression versus a staged if/else sequence is a bit of personal preference. My preference is the single boolean expression; to me that logical expression is clearer than a cluttered if/else sequence. But apparently I'm weird. Most people prefer the if/else construct.
Edit, per request
As a single boolean expression,
bool Person::operator< (const Person& other) const {
return (last_name < other.last_name) ||
((last_name == other.last_name) &&
((first_name < other.first_name) ||
((first_name == other.first_name) &&
(middle_name < other.middle_name))));
}
I find the first one the most difficult to read of the three (although none of them are too difficult) and the first one has unnecessary parentheses. The second one is my personal preference, because the third one seems too long and verbose.
This really is subjective though.
I normally write a comparison function roughly like this:
bool whatever::operator<(whatever const &other) {
if (key1 < other.key1)
return true;
if (other.key1 < key1)
return false;
// compare the second key item because the first ones were equal.
if (key2 < other.key2)
return true;
if (other.key2 < key2)
return false;
// repeat for as many keys as needed
// for the last key item, we can skip the second comparison:
if (keyN < other.keyN)
return true;
return false; // other.keyN >= keyN.
}
Along a slightly different vein, all of the solutions (including my first answer) tend to compare names twice, once for less than and again for equality. Since sort is at best an N*logN algorithm, efficiency can be quite important when sorting a big list of names, and these duplicative comparisons are rather inefficient. The string::compare method provides a mechanism for bypassing this problem:
bool Person::operator< (const Person& other) const {
int cmp = last_name.compare (other.last_name);
if (cmp < 0) {
return true;
} else if (cmp == 0) {
cmp = first_name.compare (other.first_name);
if (cmp < 0) {
return true;
} else if (cmp == 0) {
cmp = middle_name.compare (other.middle_name);
if (cmp < 0) {
return true;
}
}
}
return false;
}
Edit, per request
Elided.
A boolean version of the above will either result in undefined behavior or will use multiple embedded uses of the ternary operator. It is ugly even given my penchant for hairy boolean expressions. Sorry, Mankarse.
I like to reduce this to tuples, which already implement this kind of lexicographical ordering. For example, if you have boost, you can write:
bool Person::operator< (const Person& Rhs) const
{
return boost::tie(m_Last, m_First, m_Middle) < boost::tie(Rhs.m_Last, Rhs.m_First, Rhs.m_Middle);
}
can this be done somehow?
if((a || b) == 0) return 1;
return 0;
so its like...if a OR b equals zero, then...but it is not working for me.
my real code is:
bool Circle2::contains(Line2 l) {
if((p1.distanceFrom(l.p1) || p1.distanceFrom(l.p2)) <= r) {
return 1;
}
return 0;
}
You need to write the full expression:
(a==0)||(b==0)
And in the second code:
if((p1.distanceFrom(l.p1)<= r) || (p1.distanceFrom(l.p2)<=r) )
return 1;
If you do ((a || b) == 0) this means "Is the logical or of a and b equal to 0. And that's not what you want here.
And as a side note: the if (BooleanExpression)return true; else return false pattern can be shortened to return BooleanExpression;
You have to specify the condition separately each time:
if (a == 0) || (b == 0))
bla bla;
When you do
if ((a || b) == 0)
bla bla;
it has a different meaning: (a || b) means "if either a or b is non-zero (ie. true), then the result of this expression is true".
So when you do (a||b) == 0, you are checking if the result of the previously explained expression is equal to zero (or false).
The C++ language specifies that the operands of || ("or") be boolean expressions.
If p1.distanceFrom(l.p1) is not boolean (that is, if distanceFrom returns int, or double, or some numeric class type), the compiler will attempt to convert it to boolean.
For built in numeric type, the conversion is: non-zero converts to true, zero converts to false. If the type of p1.distanceFrom(l.p1) is of class type Foo, the compiler will call one (and only one) user defined conversion, e.g., Foo::operator bool(), to convert the expression's value to bool.
I think you really want something like this:
bool Circle2::contains(Line2 l) {
if((p1.distanceFrom(l.p1) <= r) || (p1.distanceFrom(l.p2) <= r)) return 1;
return 0;
}
Fun with templates:
template <typename T>
struct or_t
{
or_t(const T& a, const T& b) : value1(a), value2(b)
{
}
bool operator==(const T& c)
{
return value1 == c || value2 == c;
}
private:
const T& value1;
const T& value2;
};
template <typename T>
or_t<T> or(const T& a, const T& b)
{
return or_t<T>(a, b);
}
In use:
int main(int argc, char** argv)
{
int a = 7;
int b = 9;
if (or(a, b) == 7)
{
}
return 0;
}
It performs the same comparison you would normally do, though, but at your convenience.
If you have lot of that code, you may consider a helping method:
bool distanceLE (Point p1, Point p2, double threshold) {
return (p1.distanceFrom (p2) <= threshold)
}
bool Circle2::contains (Line2 l) {
return distanceLE (p1, l.p1, r) && distanceLE (p1, l.p2, r);
}
If you sometimes have <, sometimes <=, >, >= and so on, maybe you should pass the operator too, in form of a function.
In some cases your intentions by writing this:
if ((a || b) == 0) return 1;
return 0;
could be expressed with an bitwise-or:
if ((a | b) == 0) return 1;
return 0;
and simplified to
return ! (a | b);
But read up on bitwise operations and test it carefully. I use them rarely and especially I didn't use C++ for some time.
Note, that you inverted the meaning between your examples 1 and 2, returning true and false in the opposite way.
And bitwise less-equal doesn't make any sense, of course. :)
C++ doesn't support any construct like that. Use if (a == 0 || b == 0).
Your condition should be (a == 0 || b == 0) or (p1.distanceFrom(l.p1) <= r || p1.distanceFrom(l.p2)) <= r)
C++ isn't that smart. You have to do each comparison manually.
bool Circle2::contains(Line2 l) {
if((p1.distanceFrom(l.p1) <= r) || (p1.distanceFrom(l.p2) <= r)) return 1;
return 0;
}