I have been trying to implement the shunting yard algorithm, but the output of my parser is incorrect.
let mut stack: Vec<String> = vec![];
let mut op_stack: Vec<String> = vec![];
for current in sub_tree {
if current.tok_type == TokenType::NUMBER || current.tok_type == TokenType::NEGNUMBER {
self.parse();
stack.push(current.content.clone());
}
if current.tok_type == TokenType::SUBBIN
|| current.tok_type == TokenType::PLUSBIN
|| current.tok_type == TokenType::DIVBIN
|| current.tok_type == TokenType::MULBIN
{
while op_stack.len() > 0 && op_stack.last().unwrap().to_string() != "(" {
if op_prec(&op_stack.last().unwrap().to_string()) > op_prec(¤t.content)
|| (op_prec(&op_stack.last().unwrap().to_string()) == op_prec(¤t.content)
&& op_asso(¤t.content) == "left")
{
stack.push(op_stack.pop().unwrap().to_string());
} else {
break;
}
}
op_stack.push(current.content.to_string())
}
}
The original equation I am parsing: 1 + 2 * 3
I expected the following output: 1 2 3 * +
Instead I get this: 1 2 3 + *
I think I am going wrong somewhere in my while loop but I don't really know. I tried to follow the example on the Wikipedia article.
I forgot I had to pop from the operator stack back into the output stack at the end.
Comparing your code
if current.tok_type == TokenType::SUBBIN
|| current.tok_type == TokenType::PLUSBIN
|| current.tok_type == TokenType::DIVBIN
|| current.tok_type == TokenType::MULBIN
{
while op_stack.len() > 0 && op_stack.last().unwrap().to_string() != "(" {
if op_prec(&op_stack.last().unwrap().to_string()) > op_prec(¤t.content)
|| (op_prec(&op_stack.last().unwrap().to_string()) == op_prec(¤t.content)
&& op_asso(¤t.content) == "left")
{
stack.push(op_stack.pop().unwrap().to_string());
} else {
break;
}
}
op_stack.push(current.content.to_string())
}
with the Wikipedia code https://en.wikipedia.org/wiki/Shunting-yard_algorithm
- an operator o1:
while (
there is an operator o2 other than the left parenthesis at the top
of the operator stack, and (o2 has greater precedence than o1
or they have the same precedence and o1 is left-associative)
):
pop o2 from the operator stack into the output queue
push o1 onto the operator stack
It looks like they are functionally identical.
So I suspect the problem is not with the code, but instead with the precedence table. If you have the precedence of + and * the wrong way round, then you would get this behaviour. It is easy to get this mixed up as some source have precedence going from tighter binding to loser one and some have the opposite. Compare Wikipedia order of operations and Operator Precedence in Java, use the former.
Related
how to use ternary if else with two or more condition using "OR" and "AND" like
if(foo == 1 || foo == 2)
{
do something
}
{
else do something
}
i want to use it like
foo == 1 || foo == 2 ? doSomething : doSomething
If you're referring to else if statements in dart, then this ternary operator:
(foo==1)? something1():(foo==2)? something2(): something3();
is equivalent to this:
if(foo == 1){
something1();
}
elseif(foo == 2){
something2();
}
else something3();
For three conditions use:
value: (i == 1) ? 1 : (i == 2) ? 2 : 0
Try below
(2 > 3)?print("It is more than 3"):print("It is less than 3");
////Prints It is less than 3 to the console
For AND try this,
// here both or multiple conditions needs to satisfy
if (primaryImageUploaded == true && signatureImageUploaded == true) {
// status bool condition in true
} else {
// if false
}
For OR try this,
// here need ONLY any one condition to satisfy
if (primaryImageUploaded == true || signatureImageUploaded == true) {
// status bool condition in true
} else {
// if false
}
Another Dart Syntax
if (100 > 50) {
print("100 is greater than 50");
}
it is easy,
if(foo == 1 || foo == 2)
{
do something
}
{
else do something
}
it can be written thus for OR statement
foo==1 || foo==2 ? do something : else do something
it can be written thus for AND statement
foo==1 && foo==2 ? do something : else do something
both will work perfectly
EDITED
The original answer has run a little bit of from the question asked. Below is my edited answer.
To use ternary operator
(foo == 1 || foo == 2) ? doSomething() : doSomethingElse();
For my cleaner approach
{1, 2}.contains(foo) ? doSomething() : doSomethingElse();
ORIGINAL
The cleaner way for me is
if ({1, 2}.contains(foo)) {
//do something
} else {
//do something else
}
Here is an example of the same
Text((managerStatus == "pending")
? "Requested"
: (adminStatus == "confirm")
? "Amount credited"
: "Admin Pending")
Try this:
foo == 1 ? doSomething1 : (foo == 2 ? doSomething1 : doSomething2)
If you have to include multiple conditions then you should use parantheses
Simple Multiple check in one condition
if(in_array($foo, [1,2,'other'])) {
//do something
}
else {
//else do something
}
void main(){
var a,b,c,d;
a = 7;
b = 9;
c = 11;
d = 15;
print((a>b)?((a>c)?((a>d)?a:d):c):(b>c)?((b>d)?b:d):(c>d)?c:d);
}
I want to do something like this with an optional in swift.
var opt:MyOptional?
func myfunction() {
if (opt == nil) || (opt?.x != 10 && opt?.y != 20)) {
opt = MyOptional()
opt.x = 10
opt.y = 20
}
}
My question is if this is a valid pattern, even though it compiles and runs. Does Swift compiler ensures condition 2 runs after condition 1 (opt!= nil)?
Well && and || operators in swift are Left Associative which means your evaluation of conditions goes from left hand side.
(opt != nil). // result 1
this condition will get evaluate first and as you are using the || operator.
Secondaly your (opt?.x != 10 && opt2?.y != 20) // result 2
will get now evaluate if your result 1 is false otherwise it would have gone in the loop because of || operator
final condition
if (result 1 || result 2) {
if only result 1 is true it not evaluate for result 2 due to || operator otherwise it would calculate result 2 and if result 2 is true its a success
Assuming you have got a typo this code should looks like this:
struct MyOptional {
var x: Int = 0
var y: Int = 0
}
class SomeClass {
var opt: MyOptional?
func myFunction() {
if let unwrappedOpt = opt,
unwrappedOpt.x != 10 && unwrappedOpt.y != 20 {
opt = MyOptional(x: 10, y: 20)
}
}
}
What about your question? You are right.
I'm trying to filter an array in swift, it works great when I'm just trying to filter a few things but when I add to the list I get this error:
Expression was too complex to be solved in reasonable time; consider
breaking up the expression into distinct sub-expressions
Here is my code with the above error:
filteredArray = workArray.filter { $0.stateName.localizedCaseInsensitiveContainsString(searchString!) || $0.firstName.localizedCaseInsensitiveContainsString(searchString!) || $0.lastName.localizedCaseInsensitiveContainsString(searchString!) || $0.countyName.localizedCaseInsensitiveContainsString(searchString!) || $0.cityName.localizedCaseInsensitiveContainsString(searchString!) || $0.communityName.localizedCaseInsensitiveContainsString(searchString!) || $0.sectionName.localizedCaseInsensitiveContainsString(searchString!) || $0.notes.localizedCaseInsensitiveContainsString(searchString!) || $0.email1.localizedCaseInsensitiveContainsString(searchString!) || $0.email2.localizedCaseInsensitiveContainsString(searchString!) || $0.email3.localizedCaseInsensitiveContainsString(searchString!) || $0.title.localizedCaseInsensitiveContainsString(searchString!) || $0.jobsiteID.localizedCaseInsensitiveContainsString(searchString!)}
I have tried to split this process up like this
filteredArray = workArray.filter { $0.stateName.localizedCaseInsensitiveContainsString(searchString!) || $0.firstName.localizedCaseInsensitiveContainsString(searchString!) || $0.lastName.localizedCaseInsensitiveContainsString(searchString!) || $0.countyName.localizedCaseInsensitiveContainsString(searchString!) || $0.cityName.localizedCaseInsensitiveContainsString(searchString!) || $0.communityName.localizedCaseInsensitiveContainsString(searchString!) || $0.sectionName.localizedCaseInsensitiveContainsString(searchString!) || $0.notes.localizedCaseInsensitiveContainsString(searchString!) || $0.email1.localizedCaseInsensitiveContainsString(searchString!)}
and
filteredArray.appendContentsOf(workArray.filter { $0.email2.localizedCaseInsensitiveContainsString(searchString!) || $0.email3.localizedCaseInsensitiveContainsString(searchString!) || $0.title.localizedCaseInsensitiveContainsString(searchString!) || $0.jobsiteID.localizedCaseInsensitiveContainsString(searchString!)})
But I am getting duplicate objects in the array.
I could write something else that would then look for and delete duplicate objects but I would rather not. My question is how should I be filtering all this items.
Thank you for all the help
Factor that behemoth of an expression out to a method on your datatype.
extension MyDataThingy {
func anyFieldContains(searchTerm term: String) -> Bool {
let fieldValues = [self.stateName, self.firstName, /* etc. */]
for value in fieldValues {
if value.localizedCaseInsensitiveContainsString(term) {
return true
}
}
return false
}
}
Then:
filteredArray = workArray.filter { $0.anyFieldContains(searchTerm: searchTerm) }
This will fix the timeout error from the type inference engine. It is also more readable, more understandable, and more maintainable.
Extended syntax
Try the extended syntax
workArray.filter { elm -> Bool in
// put your conditions here
}
this way you are helping the compiler to understand that the closure receive an element of the type of your array and returns a Bool value.
I have a question about Objective C
I want an inverted if statement. Like: if (!example.hidden == YES) {
Here's my code:
if ((randomBallTouch.x>_randomColorBall.center.x-(_randomColorBall.frame.size.width)/2) &&
(randomBallTouch.x<_randomColorBall.center.x+(_randomColorBall.frame.size.width)/2) &&
(randomBallTouch.y>_randomColorBall.center.y-(_randomColorBall.frame.size.height)/2) &&
(randomBallTouch.y<_randomColorBall.center.y+(_randomColorBall.frame.size.height)/2)) {
_randomColorBall.center = CGPointMake(randomBallTouch.x, randomBallTouch.y);
if (_randomColorBall.hidden == NO) {
_redBall.center = CGPointMake(_redBall.center.x, _redBall.center.y - 200);
}
}
But when i do: if(!(randomBallTouch.x>_randomColorBall.center.x)) etc. It does not work.
And I can't do else because that will bug with the other two if statements.
Any help?? I am using Xcode 5.1.
You can't just add an ! at the beginning to invert the condition. You need to wrap the whole expression in a set of parentheses first.
If you have:
if (a && b) {
then the inversion is:
if (!(a && b)) {
You didn't add those parentheses.
Try this, just replace your if with this one.
if(!((randomBallTouch.x > (_randomColorBall.center.x-(_randomColorBall.frame.size.width)/2)) && (randomBallTouch.x < (_randomColorBall.center.x+(_randomColorBall.frame.size.width)/2)) && (randomBallTouch.y > (_randomColorBall.center.y-(_randomColorBall.frame.size.height)/2)) &&(randomBallTouch.y < (_randomColorBall.center.y+(_randomColorBall.frame.size.height)/2)))) {
You are missing a lot of parenthesis to make your statement a valid boolean.
I am reviewing scripts written by differenct coders and see many statement like:
((patindex('%,'+rtrim(ad.Dept)+',%', #vcP1Input) != 0) .
and I am wondering what the '!' is being used for.
! means not in this case.
So the != means not equal.
It means inequality.
Left side (patindex('%,'+rtrim(ad.Dept)+',%', #vcP1Input) is not equal to right side (0)
!= is the negation of ==
for example
if(obj == null)
{
// do stuff1
}
else
{
// do stuff2
}
is the same like
if(obj != null)
{
// do stuff2
}
else
{
// do stuff1
}
In TSQL, != means not equal to.
Your expression
((PATINDEX('%,' + RTRIM(ad.Dept)+',%', #vcP1Input) != 0)
is true if it can find the the trimmed value of ad.Dept in the string #vcP1Input, that is if PATINDEX returns anything else than 0.