After some google search I find it!
Prefix to Infix
This algorithm is a non-tail recursive method.
The reversed input string is completely pushed into a stack.
prefixToInfix(stack)
1) IF stack is not empty
a. Temp -->pop the stack
b. IF temp is a operator
i. Write a opening parenthesis to output
ii. prefixToInfix(stack)
iii. Write temp to output
iv. prefixToInfix(stack)
v. Write a closing parenthesis to output
c. ELSE IF temp is a space -->prefixToInfix(stack)
d. ELSE
i. Write temp to output
ii. IF stack.top NOT EQUAL to space -->prefixToInfix(stack)
when the Stack top is
F(ABC)
and we enter the algorithm, "A" is written to the output as it was currently the value of
temp=A (say)
Now how I get '-' on the output column as according to the algorithm the next temp value will be "B" which was popped from the stack after the last recursive call.
How the diagram is showing output "((A-" ...
Where I am doing the incorrect assumption ?
Could someone take the trouble in explaining it ?
I don't quite understand your question.
If your stack is ABC, F(ABC) pops the A, goes into branch d.i. and writes an A to output, goes on into d.ii. and performs F(BC), which will, in the end, write both the B and C to output.
If you want your output to look like it does on the diagram, you'll need your stack to be * - A B C (note the spaces between every element!).
Edit:
(As an aside: all this is easier stepped through than described, so I suggest you write the algorithm as a program and start it in your choice of debugger.)
OK, so you have stored the first * in temp (a), written a ( (b.i.), and called the algorithm with the remaining stack (b.ii.). This throws away a blank, then you store a - in the next branch's temp, write a (, and called the algorithm with the remaining stack. At some point, you end up in d.ii., you have just written an A to output, giving you
((A
and the remaining stack is
_B_C
with a space on top and another space between B and C.
So now d.ii. finds the space and doesn't do anything anymore: this control branch is done, and we go back to where we came from, which was d.ii. in your - control branch. You write the - to output at d.iii., call the algorithm with the remaining stack (_B_C) at d.iv., and there you go, writing the B, a ), the * and C and the last ).
Just remember where you came from, so you know where to jump back after your current recursion is done.
Related
This is my situation: the input is a string that contains a normal mathematical operation like 5+3*4. Functions are also possible, i.e. min(5,A*2). This string is already tokenized, and now I want to parse it using stacks (so no AST). I first used the Shunting Yard Algorithm, but here my main problem arise:
Suppose you have this (tokenized) string: min(1,2,3,+) which is obviously invalid syntax. However, SYA turns this into the output stack 1 2 3 + min(, and hopefully you see the problem coming. When parsing from left to right, it sees the + first, calculating 2+3=5, and then calculating min(1,5), which results in 1. Thus, my algorithm says this expression is completely fine, while it should throw a syntax error (or something similar).
What is the best way to prevent things like this? Add a special delimiter (such as the comma), use a different algorithm, or what?
In order to prevent this issue, you might have to keep track of the stack depth. The way I would do this (and I'm not sure it is the "best" way) is with another stack.
The new stack follows these rules:
When an open parentheses, (, or function is parsed, push a 0.
Do this in case of nested functions
When a closing parentheses, ), is parsed, pop the last item off and add it to the new last value on the stack.
The number that just got popped off is how many values were returned by the function. You probably want this to always be 1.
When a comma or similar delimiter is parsed, pop from the stack, add that number to the new last element, then push a 0.
Reset so that we can begin verifying the next argument of a function
The value that just got popped off is how many values were returned by the statement. You probably want this to always be 1.
When a number is pushed to the output, increment the top element of this stack.
This is how many values are available in the output. Numbers increase the number of values. Binary operators need to have at least 2.
When a binary operator is pushed to the output, decrement the top element
A binary operator takes 2 values and outputs 1, thus reducing the overall number of values left on the output by 1.
In general, an n-ary operator that takes n values and returns m values should add (m-n) to the top element.
If this value ever becomes negative, throw an error!
This will find that the last argument in your example, which just contains a +, will decrement the top of the stack to -1, automatically throwing an error.
But then you might notice that a final argument in your example of, say, 3+ would return a zero, which is not negative. In this case, you would throw an error in one of the steps where "you probably want this to always be 1."
I'm trying to Draw a npda for this language but cant seem to get it
I want to know how to Write the sequence of moves done by the npda for the input sequence w = aacb. and Is the string w accepted?
thanks I just cant seem to do this
Read at least two a's without touching the stack. Crash if you see anything else.
Continue reading a's and pushing one a onto the stack for each a you read.
If you read a c, then you must read a b immediately afterward or crash. Do not change the stack.
If you read a b, prepare to begin reading (ac) over and over again. Do not change the stack.
If the stack is not empty, you must read an a and then c or crash. If you do read a and then c, pop a single a from the stack.
Continue until you crash or the stack becomes empty after reading (ac) multiple times. If the input is exhausted, accept. Otherwise, crash.
Please let me know if you would like to see a state transition diagram to make this more concrete. I encourage you to try writing your own first.
I am trying to figure out how to do arithmetic expressions in Pushdown Automata ?(PDA) for example L=W|W=An Bm Cn-m
What i am thinking of doing is to push As then pop Bs and then either pop As with C or Bs with C depending what is left. For example aaabbc (pushing aaa then popping with Bs bba and then either pop A with C or B with C depending which one is bigger.
For a word w to be in the language, it has to have n>=m by your definition (otherwise C^(n-m) is negative, and that's impossible).
So, your automaton basically needs to:
Push to stack when seeing 'a'
pop from stack upon seeing 'b'
pop from stack upon seeing 'c'.
Also, some important issues:
You need to move between different states when seeing a 'new'
character.
Your automaton should accept w=eps (empty word).
w=a^b b^n is also in the language, make sure you take care of that.
I hope I gave you good enough leads to solve it on your own..
Good luck!
Say I've something like this: (predict the output)
void abc (char *s){
if(s[0]=='\0')
return;
abc(s+1);
abc(s+1);
printf(“%c “, s[0]);
}
It's not tough to solve, but I take too much time doing it and I've to redo such questions 2-3 times because I lose track of the recursion and values of variables(especially when there are 2-3 such recursive statements)
Is there any good method to use when one has to solve such questions?
The basic technique is to first start with a small input. Then try with one larger. Then try with one larger than that. For recursive functions, a pattern should emerge that lets you predict what the next one will look like given you know what the previous one looked like.
So, let's start with an empty string. Easy, nothing is printed.
input: ""
output:
Next is a string of length one. Almost as easy, the two recursive calls each do nothing (empty string case), and then the string's character is printed.
input: "z"
output: z
Next is a string of length two. Each of the recursive calls end up printing the second character (string of length one case), and then the first character is printed.
input: "yz"
output: zzy
So, let's try to predict what will happen for the string of length three case. What will happen is that the substring that excludes the first character gets worked on twice, then the first character is printed. That substring is the string of length two case. So:
input: "xyz"
output: zzyzzyx
So, it should be clear now how to derive the next output sequence given the current output sequence.
The easiest example for analyzing recursion is Fibonacci and Factorial function.
This will help you in analyzing recursive functions in a better manner. Whenever you lose track of recursive functions just recall these examples.
Take a stack of index cards of an appropriate size. Start tracing the initial call to the recursive function. When you get another call start a new index card and either put it in front of the first card or behind it (as appropriate). Sooner or later you will (unless you are tracing an infinite recursion) trace the execution of a call which does not make a recursive call, in which case copy the return value back to the card you came from.
It's probably a good idea to include 'go to card X' and 'came from card Y' on your cards.
In complicated situations you might find it useful to create more than one stack of cards to trace your function calls, oh why the heck, why not call them call stacks.
I have a list L and I need to split each element into a separate list and again append them together. This is the code I made for the same.
split([],[]).
split([H|T],Ls):-split(T,Ls),splist(H,[]).
make(Val,[H1|List],[H1|Res]):- make(Val,List,Res). make(Val, List,[Val|List]).
splist(H,L2):- make(Sum,[],L1),append(L1,L2,NewL).
When I use this code, each element of L is passed recursively from split() to splist() and made into a list L1 with single element by make(). I need append to keep concatenating L1 and L2. But it does not so so
For example, I have L=[1,2,3]. Now I need the following process to be done.
H=1, L1=[1] and L2=[1]. Next H=2, L1=[2] and L2=[1,2]. Next H=3, L1=[3] and L2=[1,2,3].
I need the output as mentioned above, but this is what my code does.
H=1, L1=[1], and L2= [1]. Next H=2, L1=[2] and L2=[2]. Next H=3, L1=[3] and L2=[3].
I can't make any sense out of your code. make definition is incomplete. As is, it does nothing and then fails.
Your split is equivalent to split(X,[]):- reverse(X,R), maplist(spl([]),R). with spl(B,A):-splist(A,B)., i.e. it tries splist(H,[]) for each element H of the input list X, backwards, to see whether it fails or not - that's its only outcome, as the arguments are fixed - H and [].
naming your predicates split and splist is a very bad idea - we humans are wired to distinguish words from their start, and the only different letter in these names is hidden way far near the end. IOW the two names are very similar, and it is very easy to misread and mistype them.
lastly, for splist(H,L2):- make(Sum,[],L1),append(L1,L2,NewL)., since make cn only fail, so will splist. But even if make were to produce something in L1 out of thin air - Sum starts out uninstantiated mind you - what does it say about L2? That it can be appended to the list L1? Any list can be appended to any other, saying that is saying nothing.
?? :)