https://leetcode.com/problems/decode-ways/
my solution:
class Solution {
public:
int numDecodings(string s) {
vector<int> dp(s.size(),0);
for(int i=0;i<s.size();i++)
{
int x =0;
if(s[i]-'0'>0 && s[i]-'0'<=9)
{
x = (i>0)? dp[i-1]:1;
}
if(i!=0 && stoi(s.substr(i-1,2))<=26)
{
cout<<i<<" ";
x = x + (i>=2 )? dp[i-2]:1;
}
dp[i] =x;
}
return dp[s.size()-1];
}
};
Running this code gives this error
Line 924: Char 34: runtime error: addition of unsigned offset to 0x602000000010 overflowed to 0x60200000000c (stl_vector.h)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_vector.h:933:34
My question is does the conditional operator evaluate dp[i-2] in (i>=2 )? dp[i-2]:1; even if the condition doesn't satisfy? Replacing it with a normal if-else solved my problem.
This line:
x = x + (i>=2) ? dp[i-2] : 1;
is likely not doing what you intend. The ternary ?: has lower precedence than +, so the statement actually becomes:
x = (x + (i>=2)) ? dp[i-2] : 1;
which means you are checking the trueness of x + (i>=2) instead of just i>=2. This is why dp[i-2] can be evaluated even when i < 2, because the entire expression x + (i>=2) could still be true.
You can fix this by putting explicit parentheses yourself:
x = x + ((i>=2) ? dp[i-2] : 1);
or rewriting it like this:
x += i>=2 ? dp[i-2] : 1;
This line doesn't evaluate the way you think it does.
x = x + (i>=2 )? dp[i-2]:1;
Per this page, the addition operator has a higher precedence than the ternary operator. Placing the ternary expression in parentheses should provide the desired behavior.
x += ((i>=2 ) ? dp[i-2] : 1); gets the job done. Even though I changed the operator to remove the redundant x, the parentheses are still necessary.
Related
I'm confused about direct assignment and ternary conditional operators precedence:
#include<stdio.h>
int main(void)
{
int j, k;
j = k = 0;
(1 ? j : k) = 1; // first
printf("%d %d\n", j, k);
j = k = 0;
1 ? j : k = 1; // second
printf("%d %d\n", j, k);
return 0;
}
I would expect the output to be:
1 0
1 0
But it happens to be:
1 0
0 0
Plus I get this warning:
main.cpp:20: warning: statement has no effect
which is about the line I commented as second.
Since the direct assignment operator has less precedence than the ternary conditional operator, I was expecting lines commented as first and second to be equivalent. But alas it is not the case.
I tried this with g++ --version (Ubuntu 4.4.3-4ubuntu5) 4.4.3
The operator precedence in the C/C++ language in not defined by a table or numbers, but by a grammar. Here is the grammar for conditional operator from C++0x draft chapter 5.16 Conditional operator [expr.cond]:
conditional-expression:
logical-or-expression
logical-or-expression ? expression : assignment-expression
The precedence table like this one is therefore correct when you use assignment on the left side of the doublecolon, but not when used on the right side. What is the reason for this asymmetry I have no idea. It may be a historical reason: in C the conditional result was not lvalue, therefore assigning something to it had no sense, and allowing assignment to be accepted without parentheses might seem smart at that time.
The second line is equivalent to:
1 ? (j) : (k = 1);
That's the same as:
j;
That's the same as:
;
The key is that the two operands of the ternary conditional operator can be expressions, so operator precedence isn't relevant here. It's simply that the second operand is the assignment expression k = 1.
(1 ? j : k) = 1;
is equivalent to,
if(true) j = 1;
else k = 1;
And,
1 ? j : k = 1;
is equivalent to,
if(true) j; // warning: statement has no effect
else k = 1;
In the second case,
1 ? j : k = 1;
is evaluated as:
(1) ? (j) : (k = 1);
and since one evaluates to true, the expression evaluates to j which does nothing.
I need to know the explanation of this sentence in C++
I am editing a library for BL0937 where it uses energy monitoring paramteres , I have just used a b c for simplicity
b = (c > 5) ? a/c/2 : 0;
That can be rewritten as
if(c>5)
{
b = (a/c)/2;
}
else
{
b = 0;
}
x ? y : z is a ternary operator that means "if x, then y, otherwise z."
a/c/2 is just a simple chain of division. As the division operator (/) evaluates from left to right, it is equivalent to (a/c)/2.
So your expression first evaluates c>5 and if that is true, it will evaluate to a/c/2, and otherwise 0. The evaluated value (either a/c/2 or 0) will be assigned to the variable b.
I'll mention more rules of operator precedence for c++, in case that you might be confused of the precedence of / and x ? y : z.
Here is an official page for operator precedence: https://en.cppreference.com/w/cpp/language/operator_precedence
From this, you know operator / has much priority to x ? y : z and =, and thus it is firstly calculated from left to right, i.e. a/c/2 equals (a/c)/2. And then x ? y : z has the same precedence as =, calculated from right to left. Now it means:
b = ( (c>5) ? ((a/c)/2) : 0 );
Hope it helps.
I'm confused about direct assignment and ternary conditional operators precedence:
#include<stdio.h>
int main(void)
{
int j, k;
j = k = 0;
(1 ? j : k) = 1; // first
printf("%d %d\n", j, k);
j = k = 0;
1 ? j : k = 1; // second
printf("%d %d\n", j, k);
return 0;
}
I would expect the output to be:
1 0
1 0
But it happens to be:
1 0
0 0
Plus I get this warning:
main.cpp:20: warning: statement has no effect
which is about the line I commented as second.
Since the direct assignment operator has less precedence than the ternary conditional operator, I was expecting lines commented as first and second to be equivalent. But alas it is not the case.
I tried this with g++ --version (Ubuntu 4.4.3-4ubuntu5) 4.4.3
The operator precedence in the C/C++ language in not defined by a table or numbers, but by a grammar. Here is the grammar for conditional operator from C++0x draft chapter 5.16 Conditional operator [expr.cond]:
conditional-expression:
logical-or-expression
logical-or-expression ? expression : assignment-expression
The precedence table like this one is therefore correct when you use assignment on the left side of the doublecolon, but not when used on the right side. What is the reason for this asymmetry I have no idea. It may be a historical reason: in C the conditional result was not lvalue, therefore assigning something to it had no sense, and allowing assignment to be accepted without parentheses might seem smart at that time.
The second line is equivalent to:
1 ? (j) : (k = 1);
That's the same as:
j;
That's the same as:
;
The key is that the two operands of the ternary conditional operator can be expressions, so operator precedence isn't relevant here. It's simply that the second operand is the assignment expression k = 1.
(1 ? j : k) = 1;
is equivalent to,
if(true) j = 1;
else k = 1;
And,
1 ? j : k = 1;
is equivalent to,
if(true) j; // warning: statement has no effect
else k = 1;
In the second case,
1 ? j : k = 1;
is evaluated as:
(1) ? (j) : (k = 1);
and since one evaluates to true, the expression evaluates to j which does nothing.
This (note the comma operator):
#include <iostream>
int main() {
int x;
x = 2, 3;
std::cout << x << "\n";
return 0;
}
outputs 2.
However, if you use return with the comma operator, this:
#include <iostream>
int f() { return 2, 3; }
int main() {
int x;
x = f();
std::cout << x << "\n";
return 0;
}
outputs 3.
Why is the comma operator behaving differently with return?
According to the Operator Precedence, comma operator has lower precedence than operator=, so x = 2,3; is equivalent to (x = 2),3;. (Operator precedence determines how operator will be bound to its arguments, tighter or looser than other operators according to their precedences.)
Note the comma expression is (x = 2),3 here, not 2,3. x = 2 is evaluated at first (and its side effects are completed), then the result is discarded, then 3 is evaluated (it does nothing in fact). That's why the value of x is 2. Note that 3 is the result of the whole comma expression (i.e. x = 2,3), it won't be used to assign to x. (Change it to x = (2,3);, x will be assigned with 3.)
For return 2,3;, the comma expression is 2,3, 2 is evaluated then its result is discarded, and then 3 is evaluated and returned as the result of the whole comma expression, which is returned by the return statement later.
Additional informations about Expressions and Statements
An expression is a sequence of operators and their operands, that specifies a computation.
x = 2,3; is expression statement, x = 2,3 is the expression here.
An expression followed by a semicolon is a statement.
Syntax: attr(optional) expression(optional) ; (1)
return 2,3; is jump statement (return statement), 2,3 is the expression here.
Syntax: attr(optional) return expression(optional) ; (1)
The comma (also known as the expression separation) operator is evaluated from left to right. So return 2,3; is equivalent to return 3;.
The evaluation of x = 2,3; is (x = 2), 3; due to operator precedence. Evaluation is still from left to right, and the entire expression has the value 3 with the side-effect of x assuming the value of 2.
This statement:
x = 2,3;
is composed by two expressions:
> x = 2
> 3
Since operator precedence,
= has more precedence than comma ,, so x = 2 is evaluated and after 3. Then x will be equal to 2.
In the return instead:
int f(){ return 2,3; }
The language syntax is :
return <expression>
Note return is not part of expression.
So in that case the two expression will be evaluated will be:
> 2
> 3
But only the second (3) will be returned.
Try to apply the simplistic approach just highlighting the precedence with parenthesis:
( x = 2 ), 3;
return ( 2, 3 );
Now we can see the binary operator "," working in the same way on both, from left to right.
I'm confused about direct assignment and ternary conditional operators precedence:
#include<stdio.h>
int main(void)
{
int j, k;
j = k = 0;
(1 ? j : k) = 1; // first
printf("%d %d\n", j, k);
j = k = 0;
1 ? j : k = 1; // second
printf("%d %d\n", j, k);
return 0;
}
I would expect the output to be:
1 0
1 0
But it happens to be:
1 0
0 0
Plus I get this warning:
main.cpp:20: warning: statement has no effect
which is about the line I commented as second.
Since the direct assignment operator has less precedence than the ternary conditional operator, I was expecting lines commented as first and second to be equivalent. But alas it is not the case.
I tried this with g++ --version (Ubuntu 4.4.3-4ubuntu5) 4.4.3
The operator precedence in the C/C++ language in not defined by a table or numbers, but by a grammar. Here is the grammar for conditional operator from C++0x draft chapter 5.16 Conditional operator [expr.cond]:
conditional-expression:
logical-or-expression
logical-or-expression ? expression : assignment-expression
The precedence table like this one is therefore correct when you use assignment on the left side of the doublecolon, but not when used on the right side. What is the reason for this asymmetry I have no idea. It may be a historical reason: in C the conditional result was not lvalue, therefore assigning something to it had no sense, and allowing assignment to be accepted without parentheses might seem smart at that time.
The second line is equivalent to:
1 ? (j) : (k = 1);
That's the same as:
j;
That's the same as:
;
The key is that the two operands of the ternary conditional operator can be expressions, so operator precedence isn't relevant here. It's simply that the second operand is the assignment expression k = 1.
(1 ? j : k) = 1;
is equivalent to,
if(true) j = 1;
else k = 1;
And,
1 ? j : k = 1;
is equivalent to,
if(true) j; // warning: statement has no effect
else k = 1;
In the second case,
1 ? j : k = 1;
is evaluated as:
(1) ? (j) : (k = 1);
and since one evaluates to true, the expression evaluates to j which does nothing.