Im toying with the problem of prefix evaluations, and I want to evaluate them using only a queue. Here is my pseudocode
while Q has more than 1 element
if the pattern operand, number, number occurs
op=dequeue(Q)
num1=dequeue(Q)
num2=dequeue(Q)
eval=evaluate(op,num1,num2)
enqueue(Q,eval)
else
elem=dequeue(Q)
enqueue(Q,elem)
I think my logic is correct for well formed prefix operations, but I'm not sure how to account for invalid prefix syntax, such as 10+4.
Right now, my algorithm would dequeue the 10 and then enqueue it at the end, which would then become proper prefix and be evaluated, but I do not want it to. Is there some pre condition to make sure the syntax is correct?
If you have a function to pop the first element of the queue without dequeuing it, you could use it in your else path with a while(first element not operand) to dequeue the invalid elements. This would guarantee you at least, that the first item in your queue is an operand.
Related
New to C. So I saw this line of code
system->word[system->index++] = system->next_char;
Is it equivalent to:
system->word[system->index] = system->next_char;
index++;
What is the precedence for post increment? Does it only increment index's value by 1 after all the operations on the line are done executing?
Updating system->index is defined as a side effect that is not sequenced (is not specified to come before or after) the other operations in the statement. The update may occur before, during, or after other operations.
The fact that it is not sequenced is irrelevant as long as it is not used elsewhere in the statement, because, if it is not used elsewhere, then nothing the statement does can be affected by when the update occurs. (Note that, even if the update to system->index in memory is done before the value is used, the compiler is response for ensuring that the pre-update value is used.)
If the object being updated were used elsewhere in the statement in an unsequenced way (that is, no rule specifies which comes first, the update or the other use), then the behavior of the program would not be defined by the C standard.
This is not a consequence of precedence. Precedence determines the structure of how expressions are interpreted, not the sequencing of their operations.
Not.
system->word[system->index++] = system->next_char;
is equivalent to:
system->word[system->index] = system->next_char;
system->index++;
as index is a field on a struct pointed to by system. In case you have also a scalar variable named index you had had no errors but the wrong variable should have been incremented.
As a general rule, all the unary operators evaluate first on the right side of the variable, then the ones on the left (the right side operators have higher precedence thatn left side ones) and evaluate from closest to the operand, to farthest. So the operator closest to the operand evaluates first, then the one next in the right... so until there are no more right operators on the right, then the closest on the left side, and so on until there are no more left operators on the left.
So what happens if we have -x++ ? The ++ is evaluated first to the value of x and a post increment of the variable is schedule to occur, then the one on the left is evaluated, givin as result the value of x before incrementing, changed of sign, and the variable x gets its value incremented (only incremented, no sign change).
Another example: let's compute ++x->field: first of all ->field (the whole thing, the -> arrow and the field name) is considered a right unary operator, given a pointer gets the value in field named field fo structure pointed to by x. This value is incremented (and stored again in x->field) and the returned value is the final incremented one.
Another final example: let's compute *p++. The value of p is scheduled to be post incremented, but it's previous value is retained. Then the old value of p is used to access the value pointed to by it, giving the original pointed to value. Finally p is incremented and points to the value next to the value accessed.
I am programming in Fortran and if all single elements of my array are positive I want to execute statement 1, if they are partly positive execute statement 2 and if all are negative execute statement 3.
I know I will probably need a 'do' loop and a 'if' construct but could not figure out how to do it best.
There is no need to use loop for a simple condition
if (ALL(A>0)) then
statement1
else if (ALL(A<0)) then
statement3
else
statement2
end if
Explanation: A>0 is an array of logical values based on evaluating the condition for each element of the original array A. Function ALL() then reduces this logical array and returns true if all elements are true and false otherwise.
You request a do loop in the title. If you really need to fix a particular error with that, you must show us the code from your efforts, your errors and all other important details.
So I'm using an array based queue implementation.
After the array is filled, to delete the first element out, I shifted the array to the left.
This made the last element in the array zero, this also meant I can't enter a new element in to the array because the last spot is taken up by a zero.
Is there a way to completely delete the element instead of it becoming a zero?
I tried this to completely empty the queue using this, but it just turned all the elements in to zero.
case 3:
memset(queue, 0, sizeof(queue));
printf("\nThe entire queue has been emptied");
break;
Thank you.
Why don't you overwrite the last element with a new value? Let's say the queue is n elements long and you want to overwrite the last element array[n-1] with a new value e.g. 23...
array[n-1] = 23;
or
*(array+n-1) =23;
To completely delete the entry sounds like a difficult problem because you are making the array smaller, but there will still exist a bit of memory where your last element used to be. You should control your program so that it never tries to access array elements beyond the limit of your array as the results will be unpredictable.
It is really important in your code that you have a way of your program knowing how long arrays are. The computer may not stop you accessing memory beyond what is allocated for an array, but it is a very bad idea - particularly if you were to try to write to it.
So as long as you remember how long your array is all you have to do to delete the last element is reduce the length of your array by 1.
I have two arrays, say A and B with |A|=8 and |B|=4. I want to calculate the set difference A-B. How do I proceed? Please note that there are no repeated elements in either of the sets.
Edit: Thank you so much everybody for a myriad of elegant solutions. Since I am in prototyping stage of my project, for now I implemented the simplest solution told by Brian and Owen. But I do appreciate the clever use of data structures as suggested here by the rest of you, even Though I am not a computer scientist but an engineer and never studied data structures as a course. Looks like it's about time I should really start reading CLRS which I have been procrastinating for quite a while :) Thanks again!
sort arrays A and B
result will be in C
let a - the first elem of A
let b - the first elem of B
then:
1) while a < b: insert a into C and a = next elem of A
2) while a > b: b = next elem of B
3) if a = b: a = next elem of A and b = next elem of B
4) if b goes to end: insert rest of A into C and stop
5) if a goes to end: stop
Iterate over each element of A, if each of those elements are not in B, then add them to a new set C.
It depends on how you want to represent your sets, but if they are just packed bits then you can use bitwise operators, e.g. D = A & ~B; would give you the set difference A-B if the sets fit into an integer type. For larger sets you might use arrays of integer types and iterate, e.g.
for (i = 0; i < N; ++i)
{
D[i] = A[i] & ~B[i];
}
The following assumes the sets are stored as a sorted container (as std::set does).
There's a common algorithm for merging two ordered lists to produce a third. The idea is that when you look at the heads of the two lists, you can determine which is the lower, extract that, and add it to the tail of the output, then repeat.
There are variants which detect the case where the two heads are equal, and treat this specially. Set intersections and unions are examples of this.
With a set asymmetric difference, the key point is that for A-B, when you extract the head of B, you discard it. When you extract the head of A, you add it to the input unless the head of B is equal, in which case you extract that too and discard both.
Although this approach is designed for sequential-access data structures (and tape storage etc), it's sometimes very useful to do the same thing for a random-access data structure so long as it's reasonably efficient to access it sequentially anyway. And you don't necessarily have to extract things for real - you can do copying and step instead.
The key point is that you step through the inputs sequentially, always looking at the lowest remaining value next, so that (if the inputs have no duplicates) you will the matched items. You therefore always know whether your next lowest value to handle is an item from A with no match in B, and item in B with no match in A, or an item that's equal in both A and B.
More generally, the algorithm for the set difference depends on the representation of the set. For example, if the set is represented as a bit-vector, the above would be overcomplex and slow - you'd just loop through the vectors doing bitwise operations. If the set is represented as a hashtable (as in the tr1 unordered_set) the above is wrong as it requires ordered inputs.
If you have your own binary tree code that you're using for the sets, one good option is to convert both trees into linked lists, work on the lists, then convert the resulting list to a perfectly balanced tree. The linked-list set-difference is very simple, and the two conversions are re-usable for other similar operations.
EDIT
On the complexity - using these ordered merge-like algorithms is O(n) provided you can do the in-order traversals in O(n). Converting to a list and back is also O(n) as each of the three steps is O(n) - tree-to-list, set-difference and list-to-tree.
Tree-to-list basically does a depth-first traversal, deconstructing the tree as it goes. Theres a trick for making this iterative, storing the "stack" in part-handled nodes - changing a left-child pointer into a parent-pointer just before you step to the left child. This is a good idea if the tree may be large and unbalanced.
Converting a list to a tree basically involves a depth-first traversal of an imaginary tree (based on the size, known from the start) building it for real as you go. If a tree has 5 nodes, for instance, you can say that the root will be node 3. You recurse to build a two-node left subtree, then grab the next item from the list for that root, then recurse to build a two-node right subtree.
The list-to-tree conversion shouldn't need to be implemented iteratively - recursive is fine as the result is always perfectly balanced. If you can't handle the log n recursion depth, you almost certainly can't handle the full tree anyway.
Implement a set object in C. You can do it using a hash table for the underlying storage. This is obviously a non trivial exercise, but a few Open Source solutions exist. Then you simply need to add all the elements of A and then iterate over B and remove any that are elements of your set.
The key point is to use the right data structure for the job.
For larger sets I'd suggest sorting the numbers and iterating through them by emulating the code at http://www.cplusplus.com/reference/algorithm/set_difference/ which would be O(N*logN), but since the set sizes are so small, the solution given by Brian seems fine even though it's theoretically slower at O(N^2).
How can I find last node of a circular linked list whose size I don't know and the last node points to any other node except first node of the linked list?
One algorithm that can be used for this is the Floyd cycle algorithm.
Also, see this question.
By definition, if a node does not point to the first node of a circular linked list,
it is not the last node.
Can you elaborate here?
A strange list... why would you ever need something like this? But anyway...
You can simply iterate over all nodes, and stop as soon as the next node would be one you have already visited. The current node will then be your answer.
You need some way to keep track of which nodes have been visited. Add a boolean flag to each node, or use some kind of set data type with fast insertion and lookup (e.g. a hash set).
Maybe add parameter to nodes of the list which tells you if you at end? I think, it wouldn't be problem.
Otherwise, you can remember nodes you already visted. When the next node is already visited, you are at the end.
The Floyd cycle algorithm won't give the last element of the list. It will only tell if there is a cycle or not.
The definition of the last one would be that, while traversing the list in a sequential scan starting from the first one, all elements before it and the last one aren't seen before (pointer value). The after last one will be the first element that has already been seen in this sequential scan.
An easy solution is to flag visited elements so an element already seen is easily detected. The flag may be intrusive, i.e. by changing a bit in the element, or external by using a hash table to store pointer values.
Since we need to be able to test if an element has already been visited, I don't see another solution.
I can elaborate on how to use Floyd's algorithm to solve this problem but I don't understand the explanation for one step
Have 2 pointers traverse the linked list, pointer 1 going at a rate of 1 node per iteration, the second going at a rate of 2 nodes
When the pointers meet, we are in the cycle and we are some distance before pointer 1 has reached the end of the cycle (we know pointer 1 hasn't reached then end because if cycle is distance d and pointer 2 is going at twice the speed of 1, pointer1 will loop the cycle twice before pointer 1 does it once)
So because they have met before pointer 1 fully traversed the cycle, we know that the meeting point is d nodes from the start and k nodes within the cycle (pos = d + k)
If we set pointer 1 to position 0 and start both points again (but at the same rate rate of 1 node per iteration), they will meet at the start of the cycle.
Since we know the start of the cycle, finding the end is trivial
I don't fully understand why step 4 is true but I had a friend explain the solution to me.