What does this C++ for-loop expression mean? - c++

I am working through the "Add Binary" problem on leetcode and a solution which I found online is the following:
#include <string>
using std::string;
class Solution {
public:
string addBinary(string a, string b) {
string ret;
bool carry{false};
for (auto apos=a.size(), bpos=b.size(); apos || bpos || carry; ) {
bool abit{apos && a[--apos] == '1'};
bool bbit{bpos && b[--bpos] == '1'};
ret = (abit ^ bbit ^ carry ? "1" : "0") + ret;
carry = abit + bbit + carry >= 2;
}
return ret;
}
};
My question is regarding the for loop above. I understand that two iterations are being instantiated with the first two expressions that are separated by a comma. However, I don't understand how the three units being or'd (ie: ||) is supposed to behave. I'm also curious why it's ok to exclude the iterator expression in this instance, ie the final expression in the for-loop.
Please help me to understand how this code functions.

basically the for loop consist of 3 parts separted by ';'(semi-colon)
1)first part, this part is about initialization of variables, again you can leave it if you want
2)second part, it defines the condition on basis of which for loop will keep running, again you can leave it if you want
3) third part, this is the part where you want to do some operations, conventially iteration value is increment, but again you can leave it if you want
so if you go with this model, I think you can easily break down what is happening in the for loop that you mentioned.

Sometimes it helps to consider the equivalent while loop:
for (auto apos=a.size(), bpos=b.size(); apos || bpos || carry; /*no increment*/) {
// ...
}
->
{
auto apos = a.size();
auto bpos = b.size();
while( apos || bpos || carry ) {
bool abit{apos && a[--apos] == '1'};
bool bbit{bpos && b[--bpos] == '1'};
ret = (abit ^ bbit ^ carry ? "1" : "0") + ret;
carry = abit + bbit + carry >= 2;
/* increment would be here*/
}
}
The loop initializes apos and bpos and continues to loop as long as the condition apos || bpos || carry yields true, ie as long as apos, bpos and carry are not all 0 (0 is converted to false any other number to true).

Related

What does this statement mean? "ret += (sx+ey)%2 ? 3 : 1, sx++;"

What does the statement is doing I've mentioned?
#include <bits/stdc++.h>
using namespace std;
int64_t dist(int64_t sx, int64_t sy, int64_t ex, int64_t ey) {
sx += ey - sy;
int64_t ret = (ey - sy)*2;
if (sx%2 != ex%2)
ret += (sx+ey)%2 ? 3 : 1, sx++; // i don't understand this line,Please explain it.
ret += (ex - sx)*2;
return ret;
This is a ternary conditional operator that lets you avoid multi-statement if-else construction while assigning a value to a variable.
The form of using it is
variable = condition ? value_if_true : value_if_false.
+= operator adds a value to some variable and is equal to ret = (ret + (sx+ey)%2 ? 3 : 1, sx++);
% operator is used to compute a remainder of two numbers.
++ is used to add 1 to a given variable and in your case it executes right after adding 1 to ret (if that condition on that line is false).
Anyway this code is really unreadable as noted in the comments, nothing bad will happen if we break it into several statements.
if (sx % 2 != ex % 2) {
if ((cx + ey)) % 2) {
ret += 3;
} else {
ret++;
}
sx++;
}
This code is quite compact.
To understand it, you must be familiar with the less not so common operators % (modulo) and ?: (conditional) as well as the operator precedences.
Not to mention that integral values can be used as booleans (0 → false, anything else → true).
And finally, the , (sequence operator) to concatenate expressions, with the last one providing the final result, (which is in this case just discarded, so that only the side effects are used).
ret += (sx+ey)%2 ? 3 : 1, sx++; // i don't understand this line,Please explain it.
can be written in a less compact form:
if (((sx + ey) % 2) != 0) { // Is the sum of sx and ey odd (not even)
ret += 3; // add 3 to ret
} else {
ret += 1; // add 1 to ret
}
++sx; // increment sx

Specify a range of ASCII lowercase chars in C++

I am writing a program that takes a char and compares it to see if it's in a range of certain chars. For instance, if the char I get is an n I go to state 3, if its a - m or o - z I go to state 4. I'm new to C++ so I'm still learning.
Can I say something like:
char c = file.next_char();
...
if (c in 'a'...'m', 'o'...'z')
{
state = 3;
} else {
state = 4;
}
There is no such syntax in C++. The options are:
Use a switch statement, when the list of values is generally not contiguous, or
Convert the list of explicit character values into contiguous ranges into equivalent boolean expressions. As you know, alphabetic characters consist of a contiguous range of octets in ASCII, so your pseudo-code is equivalent to:
if ( (c >= 'a' && c <= 'm')
||
(c >= 'o' && c <= 'z'))
If you are using ascii (English), you can rely on the fact that all the lower case letters are adjacent. Just check 'a' <= c && c <= 'z'
after ruling out 'n'.
You never said what happens if the state is not one of those, so I left it alone.
// 3 and 4 mean nothing. Give your states meaningful names
enum state_type {FirstState, SecondState, ThirdState, FourthState};
state_type state = FirstState;
char c = get_next_char();
if ('n' == c){
state = FourthState;
} else if ('a' < c && c < 'z'){
state = ThirdState;
} else {
// no change?
}
You could maybe use a for loop to compare it to see if it's a letter in the first or second range. The code would be something this:
char range1[/*amount in array here*/] = "abcdefghijklmnopqrstuvwxyz";
//Substitute range on line above(the characters in the string)
for(int i = 0; i <= /*amount in array here*/; i++) {
if(range1[i] == /*nameoflettervariablehere*/){
//Code here
}
}
I'm sorry but I don't know of a more efficient way.

Make assignment within if-statement

I have the following problem
in my app i have severeal if-statements
if ( (number >= 1 && number <= 18) && !strcmp("half1-18", _myBetCh) ) {
}
Now I realized that I have to split this condition because I need a boolean variable after one condition
bool success = false,
if(!strcmp("half1-18", _myBetCh) {
success = true;
if (number >= 1 && number <= 18) {
}
}
Is there a workaround to this? Is it possible, for instance, to make an assignment withing the if-statement?
It's possible, like this:
if ((success = !strcmp("half1-18", _myBatCh)) && number > 1 && number < 18)
but I personally think assignments in conditions are messy and hard to read, and prefer this variation:
bool success = strcmp("half1-18", _myBetCh) == 0;
if (success && number >= 1 && number <= 18) {
// ...
}
Well, there is:
if ( !strcmp("half1-18", _myBatCh) && (success = true, number > 1 && number < 18) )
or, obviating the need for the success = false earlier
if ( (success = !strcmp("half1-18", _myBatCh)) && number > 1 && number < 18 )
Your way is easier to read though, so I would consider sticking with what you've got.

Separating every second digit in an integer C++

I am currently finishing up an assignment I have to complete for my OOP class and I am struggling with 1 part in particular. Keep in mind I am still a beginner. The question is as followed:
If the string contains 13 characters, all of characters are digits and the check digit is modulo 10, this function returns true; false otherwise.
This is in regards to a EAN. I basically have to separate every second digit from the rest digits. for example 9780003194876 I need to do calculations with 7,0,0,1,4,7. I have no clue about doing this.
Any help would be greatly appreciated!
bool isValid(const char* str){
if (atoi(str) == 13){
}
return false;
}
You can start with a for loop which increments itself by 2 for each execution:
for (int i = 1, len = strlen(str); i < len; i += 2)
{
int digit = str[i] - '0';
// do something with digit
}
The above is just an example though...
Since the question was tagged as C++ (Not C, so I suggest other answerers to not solve this using C libraries, please. Let us getting OP's C++ knoweledge in the right way since the beggining), and is an OOP class I'm going to solve this with the C++ way: Use the std::string class:
bool is_valid( const std::string& str )
{
if( str.size() == 13 )
{
for( std::size_t i = 0 ; i < 13 ; i += 2 )
{
int digit = str[i] - '0';
//Do what you wan't with the digit
}
}
else
return false;
}
First, if it's EAN, you have to process every digit, not just
every other one. In fact, all you need to do is a weighted sum
of the digits; for EAN-13, the weigths alternate between 1 and
3, starting with three. The simplest solution is probably to
put them in a table (i.e. int weigt[] = { 1, 3, 1, 3... };,
and iterate over the string (in this case, using an index rather
than iterators, since you want to be able to index into
weight as well), converting each digit into a numerical value
(str[i] - '0', if isdigit(static_cast<unsigned char>(str[i])
is true; if it's false, you haven't got a digi.), then
multiplying it by the running total. When you're finished, if
the total, modulo 10, is 0, it's correct. Otherwise, it isn't.
You certainly don't want to use atoi, since you don't want the
numerical value of the string; you want to treat each digit
separately.
Just for the record, professionally, I'd write something like:
bool
isValidEAN13( std::string const& value )
{
return value.size() == 13
&& std::find_if(
value.begin(),
value.end(),
[]( unsigned char ch ){ return !isdigit( ch ); } )
== value.end()
&& calculateEAN13( value ) == value.back() - '0';
}
where calculateEAN13 does the actual calculations (and can be
used for both generation and checking). I suspect that this
goes beyond the goal of the assignment, however, and that all
your teacher is looking for is the calculateEAN13 function,
with the last check (which is why I'm not giving it in full).

while loop excluding a condition

I'm increasing a pointer and decreasing a counter in a while loop. I want to exit the loop when the counter reaches zero or the pointer is equal to a max point (IF present). That if part is giving me the problem.
Consider the following:
char * pIt = utf8str;
char ** pEnd = 0;
size_t nVal = 10;
while ( 0 < nVal && (pEnd && pIt < *pEnd || true) )
{
--nVal;
++pIt;
}
If pEnd is null, I want it to be excluded from the comparison so pIt will have no upper bound. Obviously the above code doesn't work since when pIt >= pEnd the 'or' comes into play and will always be true.
How would one do this?
Ok let's deconstruct your condition a bit. So at the top level we have two parts the counter and the iterator and both conditions must be met to continue so we have:
A && B
Now A, is the simplest and thats: nVal > 0 (it's more natural at least for me to have what I'm comparing to on the right side).
Now be is a little bit trickier. Either pEnd is null and pIt has no upper bound, or pEnd exists. Which means B == C || D. So let's sub.
A && (C || D)
Now, if pEnd is null we want it to be true right? null is false, so we want true when false so what do we do ? !pEnd. That gives us C.
Finally we have D. Which is the case where pIt has an upper bound. pIt < *pEnd.
Let's put this all together and we have:
nVal > 0 && (!pEnd || (pIt < *pEnd))
Hope this helps!
How about:
while ( 0 < nVal && (!pEnd || pIt < *pEnd) )
If you are used to reading the ternary operator, this is pretty clear:
while (0 < nVal && (pEnd ? pIt < *pEnd : true))
Just:
((pEnd == NULL) || (pIt < *pEnd))
This is not intended as an answer but as a comment with code. Shakes fist at SOs lousy comment-code options
When you run into a brain-bending logic issue and sleeping on it is not an option, deconstruct with a for(;;) loop.
for (;;) {
if (nVal <= 0)
break;
if (pEnd == nullptr) {
// logic test you want here
}
--nVal;
++pIt;
}