I have been working on writing a Java program to convert from infix notation to prefix notation using an operand stack and an operator stack. I have implemented a working converter based on the pseudocode in the top answer here:
conversion from infix to prefix
However I am now trying to work out the time and space complexity of the above algorithm.
I think that the space complexity must be O(n) because we just have two stacks that store the input shared between them.
Thinking about the time complexity, I'm not entirely sure, is it O(n^2) because of having to convert each subpart from infix to prefix? I'm not really sure about this part.
Basically my question is: is my space complexity result correct, and what is the time complexity of the algorithm?
Many thanks!
EDIT:
This is the pseudocode for the algorithm:
Algorithm ConvertInfixtoPrefix
Purpose: Convert and infix expression into a prefix expression. Begin
// Create operand and operator stacks as empty stacks.
Create OperandStack
Create OperatorStack
// While input expression still remains, read and process the next token.
while( not an empty input expression ) read next token from the input expression
// Test if token is an operand or operator
if ( token is an operand )
// Push operand onto the operand stack.
OperandStack.Push (token)
endif
// If it is a left parentheses or operator of higher precedence than the last, or the stack is empty,
else if ( token is '(' or OperatorStack.IsEmpty() or OperatorHierarchy(token) > OperatorHierarchy(OperatorStack.Top()) )
// push it to the operator stack
OperatorStack.Push ( token )
endif
else if( token is ')' )
// Continue to pop operator and operand stacks, building
// prefix expressions until left parentheses is found.
// Each prefix expression is push back onto the operand
// stack as either a left or right operand for the next operator.
while( OperatorStack.Top() not equal '(' )
OperatorStack.Pop(operator)
OperandStack.Pop(RightOperand)
OperandStack.Pop(LeftOperand)
operand = operator + LeftOperand + RightOperand
OperandStack.Push(operand)
endwhile
// Pop the left parthenses from the operator stack.
OperatorStack.Pop(operator)
endif
else if( operator hierarchy of token is less than or equal to hierarchy of top of the operator stack )
// Continue to pop operator and operand stack, building prefix
// expressions until the stack is empty or until an operator at
// the top of the operator stack has a lower hierarchy than that
// of the token.
while( !OperatorStack.IsEmpty() and OperatorHierarchy(token) lessThen Or Equal to OperatorHierarchy(OperatorStack.Top()) )
OperatorStack.Pop(operator)
OperandStack.Pop(RightOperand)
OperandStack.Pop(LeftOperand)
operand = operator + LeftOperand + RightOperand
OperandStack.Push(operand)
endwhile
// Push the lower precedence operator onto the stack
OperatorStack.Push(token)
endif
endwhile
// If the stack is not empty, continue to pop operator and operand stacks building
// prefix expressions until the operator stack is empty.
while( !OperatorStack.IsEmpty() ) OperatorStack.Pop(operator)
OperandStack.Pop(RightOperand)
OperandStack.Pop(LeftOperand)
operand = operator + LeftOperand + RightOperand
OperandStack.Push(operand)
endwhile
// Save the prefix expression at the top of the operand stack followed by popping // the operand stack.
print OperandStack.Top()
OperandStack.Pop()
End
Yep, O(n^2) looks correct - because essentially you have an outer and an inner while loop.
Edit: O(m *n) where m <= n, but still quadractic
Related
Can anyone explain to me what is this line doing? I've never seen this before, I guess.
np.Point, np.Valid = Point{}, false
As stated in this github code
This is not a three comma syntax. It is actually initializing two variables together in a line
np.Point, np.Valid = Point{}, false
is similar to
np.Point = Point{}
np.Valid = false
The Go Programming Language Specification
Assignments
A tuple assignment assigns the individual elements of a multi-valued
operation to a list of variables. There are two forms. In the first,
the right hand operand is a single multi-valued expression such as a
function call, a channel or map operation, or a type assertion. The
number of operands on the left hand side must match the number of
values. For instance, if f is a function returning two values,
x, y = f()
assigns the first value to x and the second to y. In the second form,
the number of operands on the left must equal the number of
expressions on the right, each of which must be single-valued, and the
nth expression on the right is assigned to the nth operand on the
left:
one, two, three = '一', '二', '三'
A tuple assignment assigns the individual elements of a multi-valued
operation to a list of variables. In the second form, the number of operands on the left must equal the number of > expressions on the right, each of which must be single-valued, and the nth expression on the right is assigned to the nth operand on the left.
In your example,
np.Point, np.Valid = Point{}, false
Or, equivalently,
t1 := Point{}
t2 := false
np.Point = t1
np.Valid = t2
i'm a little bit confused about the stack status for a well-known problem
, Valid Permutation of Parenthesis
there are many articles and solutions in the Internet for this and one of simple solutions is
static void allParen1( int l, int r, int n, String str ) {
if( r == n ) {
System.out.println(str + " <" + l + ": " + r + ">");
return;
}
if( l < n ) {
allParen1( l + 1, r, n, str +"(" );
}
if( r < l ) {
allParen1( l, r + 1, n, str + ")");
}
}
and if I draw a recursion tree for this code is
but I don't clearly understand that how each subtree is initiated properly.
For example, after going down the left most subtree in the figure,
it's going up to (( and then start the second left most subtree ((), ...
I draw a part of stack status of the recursion tree below.
1. My first question is how stack pops only down to ((( in the first stack (1)
which corresponds to going up the tree and then start the second left most subtree in stack (2)
in the code?
Why the stack doesn't pop down to something else like ((() or ((()) or (
in the first stack (1) in the given code?
Maybe I don't still clearly understand how recursion and backtracking works.
2.They say this problem is using backtracking.
backtracking is happening if a certain condition doesn't meet before going
further down to a recustion tree, it doesn't go gown and just branching out
to a different subtree like N-Queen problem.
Even though this problem doesn't have such condition to stop going down to a recursion tree.
how this is called backtracking problem?
If you trace the execution carefully, you'll see that the stack does pop to ((()), then to (((), then to (((, and finally (( ... which is the earliest point at which there's a second choice (a possible branch). Remember that n=3: when you first backtrack to ((()), you've already handled adding a RPAREN, and there are no more LPARENS available -- you already used all three. Similarly, you have to walk the stack back to ((, where you can finally make a choice different from the ((())) branch you just handled: you just popped the third LPAREN, and you can now replace it with a RPAREN and head down a new branch.
I'm trying to solve pretty complex problem with bracket sequence, only '(' and ')', actually I need to implement segment tree that in logarithmic time will check if sequence of brackets is valid or not.
Valid sequence of bracket is a string that is either:
The empty string
A string (B) where B is valid sequence of brackets
LR, the concentration of two strings L and R which are both valid sequences of brackets.
Now with those conditions I need to implement segment tree that for query will check if the range [A,B] is valid sequence of brackets.
Actually what I need in my program is index K such that K <= B and the sequence [A,K] is valid sequence of brackets, K is maximum possible, but I think that I cannot implement segment tree that will give me index K, so I think that I will try to implement segment tree that will only check if the sequence is valid or not.
Example
sequence = "()((()))(())" query_1 = [1,2], answer for query 1 is true because the sequence "()" is valid.
query_2=[1,6]= "()((()" this sequence is not valid and the query should return false;
What I have tried
I implemented check with stack that checks if sequence of brackets is valid or not, but that check works in O(N) and I think that we can check this in O(logN)
Thanks in advance.
Make all your ( be equal to +1, and all the ) equal to -1. Now run through the parenthesis string and create a new array out of it by cumulatively adding the value of the bracket (+1/-1). Like so:
( ) ( ( ( ) ) ) ( ( ) )
1 0 1 2 3 2 1 0 1 2 1 0
Now if some [i,j] is a valid sequence, then for every x such that i<=x<=j, [i,x] should contain more open brackets ( than closed brackets ). If ()) was a segment, it's final value would be (1)+(-1)+(-1) = -1, which is negative. This implies that the number of ) in the segment is more than the number of (s. Which is impossible in a valid sequence. Similarly for a segment ())((), although the final sum of the segment would be zero, the sum at index three (1-indexed) would be -1. So this would be invalid.
So for any query [i,j] we just have to check if in that segment, whether there exists any point x such that the sum([i,x]) <= 0. If it is, return false. Also make a check that the number of ( is equal to that of ).
For this, maintain a minimum range query segment tree of the sum array. Find the minimum value in range [i,j]. (Call that val). If val - sum[i-1] < 0 return false. Again, make a check for ( == ).
I have to draw binary tree for this expression A*(B-C+D)*P/Q
Is this one correct?
*
* /
A + P Q
- D
B C
Your tree is corresponding to this expression:
(A*(B-C+D))*(P/Q)
While technically correct, it should be like this (if you assume multiplication and division have equal precedence):
((A*(B-C+D))*P)/Q
Your answer is correct. Below are the steps to get this tree
A*(B-C+D)*P/Q
Step 1: As parentheses has maximum priority so its evaluated first.
B-C+D
But + and - has same execution priority so associativity is considered. The operators have same associativity Left to Right i.e left side must have only one operand to the operator.
Only - operator has one operand to its left so it's excecuted first and then +
So expression changes to
( (B-C) + D )
A*Z*P/Q where z=( (B-C) + D )
Step 2: * and / has same priority of evaluation, so to break the tie associativity of * and / is considered. Both the operator has same associativity Left to Right i.e left side must be unambiguous which implies that on left side of operator(* OR /) must has only one operand.
So only first * has one operand i.e A
Hence A*Z is executed next
(A*Z)*P/Q
let us rename it to
AZ*P/Q
Step 3:
Now following the associativity rule as remaining operand has same priority
* is executed first as it has only one operand on its left AZ
so,
AZP/Q
Step 4: finally / operator will be execute
AZPQ
I think You have made a mistake while writing expression .. According to me it would be A*B-(C+D)*P/Q
And for this the Binary tree would be like this ..
-
* *
A B + /
C D P Q
To be unambiguous, the expression tree could have brackets around each binary operation. So that would result in different trees for (B- C) +D and B - (C + D) , though the result would be the same due to the associative rule of addition.
While there's less clarity for human reader, the advantage of consistent bracketing is to clearly distinguish (((A*(B-(C+D)))P)/Q) from ((A(B-(C+D)))*(P/Q)).
I have a bunch of boolean expressions written in prefix notation (also called Polish notation). Nested expressions in this format are very easy to evaluate (see the algorithm in the Wikipedia article).
The algorithm given on the Wikipedia page, however, does not do short-circuiting (when it evaluates and f() g(), it does not skip the evaluation of g() if f() is false). Is there any way to modify the algorithm to include short-circuiting?
I recently needed to do this and came up with an algorithm that seems to work:
Parse the expression using shunting yard, producing a postfix term series.
Find the parent operator of each term and store the offset.
for term in terms:
count = 0
for next in remaining terms:
if next type is function:
count = count - (argument count - 1)
else if next type is operator:
count = count - 1
else:
count = count + 1
if count is 0:
next is term's parent
offset = next - term
Evaluate the usual way and check for short-circuit after each operation. Jump ahead to term after parent term if applicable.
for term in terms:
if term is operator:
pop 2 values
evaluate (in reverse order)
push result value
if short-circuit (result is 0 and parent is AND, or result is non-zero and parent is OR):
term = term + offset
else if term is function:
pop arguments
evaluate (in reverse order)
push result value
else:
push term value
You could use the same algorithm to build an expression tree: instead of evaluating operand1 operator operand2, create a node with operand1 and operand2 as children, and operator as parent.
Once you have the tree, you can evaluate it (top to bottom). You can short-circuit the evaluation by not evaluating one of the children (for example if the left child evaluates to False and the operator is and).
You'll notice that the given algorithm is equivalent to evaluation from bottom to top. While this is simple (and saves memory), you cannot apply short-circuiting because you never know if the branch you're in should even be evaluated.