If you look at the Container ADT (abstract data type) as a black box, it provides two functions:
1. put(C, x)
2. get(C)
The first function will put the object x into container C. The second will retrieve the "next" object from container C, where "next" depends on what type of container you want. A stack implementation would return the element that was most recently put into the container (also known as a FILO ADT).
My question is, in it's most generic form, does the Container ADT function get() remove the element itself from the container, or does it simply return a reference to it for access, retaining the element in the Container?
if you have only put() and get(), get() must also remove the element, otherwise you won't have access to the nth element for each n!=1.
the idea is with enough get() oporations, you should be able to access each element in the container, and if get() doesn't remove the element, sequential get()'s will always return the same element, so only the first element is accessable.
but it can be different for each implementation, of course. (for example, you can create a ADT with put(), get() and pop(), where get will only return the element.
Related
Abstract data type (ADT) : Organized data and operations on this data
Examples : Stack, Queue
what's meaning of Concrete data type (CDT)?
please explain by Examples.
One way to understand it is that an ADT is a specification of an object with certain methods.
For example if we talk about a List we are referring to an object that performs list operations such as:
add to the beginning
add to the end
insert at position
size
etc..
A "concrete data type" in this context would refer to the actual Data Structure you use to implement the list.
For example, one implementation of a List is to create nodes with a value and next pointer to point to the next node in the list.
Another is to have a value array, and a next array to tell you where the next node is (this is a more popular implementation for parallelism).
And yet another is to have a dynamic array (known as an ArrayList in Java) where you use an array till it fills up and then you duplicate it's size and copy the values to the new array.
So the concrete data type refers to the data structure actually being used, whereas the ADT is the abstract concept like List, Dictionary, Stack, Queue, Graph, etc..
There are many ways to implement an ADT.
In the oracle Java docs: https://docs.oracle.com/javase/8/docs/api/java/util/LinkedList.html:
.element() "Retrieves, but does not remove, the head (first element) of this list."
.peek() "Retrieves, but does not remove, the head (first element) of this list."
Is there a reason that you would want to use .element() as opposed to .peek()?
Is the answer to (1) is "No", why would a class need two methods with the same function?
There are 4 methods.
Peek
Element
Poll
Remove
The behaviour of peek and element is almost same with a difference:
If a queue doesnt contain any elements the peek() method returns null.
The element() method behaves like peek(), so it again retrieves the value of the first element without removing it.
However, if the list is empty element() throws a NoSuchElementException.
Lastly, there are two other methods poll and remove.
The poll() method retrieves the value of the first element of the queue by removing it from the queue. If the list doesnt contain any elements, it will return null but doesnt throw any exception.
The remove() method behaves as the poll() method, so it removes the first element of the list and if the list is empty it will throw a NoSuchElementException.
Reference:
http://www.davismol.net/2014/04/04/java-ocpjp7-difference-between-element-peek-poll-and-remove-methods-of-the-queue-interface/
The behavior is described in the docs for Queue. Basically element throws an exception if there is an error (think empty list) whereas peek just returns a special value (probably null). https://docs.oracle.com/javase/7/docs/api/java/util/Queue.html
In a constructor for a class Block i push the created instance into a static vector static std::vector<Block*> allBlocks, and remove them in the destructor.
This works if i just create blocks without pointers, ie. Block b;
However, want to have another class return a std::vector<Block*> grid for use, which creates them and adds them into the allBlocks vector also. Destroying the grid vector doesn't seem to run their destructors.
I've tried:
grid.clear() using erase/remove and just pop_back
What would be a better way to store/return them so that when the grid is destroyed, so will the contained Blocks.
Okay, so if you want a really better way, a couple of changes:
No statics! They aren't necessary at all here.
If, as you've stated, you want two containers containing those objects but in such a way that removing one object removes them from every other container, it becomes more problematic.
First, it's impossible for one container to remove elements from another unless it has a reference to it in a way. You could create a variable that would hold all of the containers of your blocks and use that to remove the block from every container, but... yeah.
In this case, a weak reference solution is acceptable, as long as you remember about the implications.
std::shared_ptr ownership and std::weak_ptr reference
Create an std::set<shared_ptr<Block>> blocks;, then two containers with weak references; might be called allBlocks or grid or whatever. Those weak references collection could be for example std::set<std::weak_ptr<Block>>.
Now when removing an element from the grid or allBlocks, you need to remove it from the blocks. To do the lookup on it, you'd need something like this:
struct null_deleter {
void operator()(void const *) const { }
};
To properly create a value for the set lookup. Then, when iterating over any other container, you'd need to use ptr.expired() on the weak_ptr reference in order to see if it was deleted previously.
The caveat of that idea is that the original shared_ptr isn't shared; the class is used just for convenience of weak_ptr and automatic destruction.
std::unique_ptr ownership and int reference
Another, perhaps simpler way is to use std::unordered_map and create a "unique ID" key for each block.
std::unordered_map<unsigned, std::unique_ptr<Block>> blocks;
Now your containers need to be std::set<unsigned>, and the lookup would look like:
for (auto b : grid) {
auto bIt = blocks.find(b);
if (bIt != blocks.end) {
// do things with *bIt
} else {
// e.g. add the b to the "delete list"
}
}
Now you could process your "delete list" and remove the dead ids from the container.
Wrapping up
Since this might get tedious to use, a nice idea could be to wrap the set into a container that would do the cleanup before returning begin() or end() for custom iteration across Block values.
Similarly, the destructor of such wrapped structure could remove the values from the map, thus effectively making all ids in all other containers dangling.
This of course raises an issue of thread safety, because the original blocks map would need to be locked for the whole iteration; at least for modification. Having cbegin()/cend() could allow two threads to read from the same shared map, but ... The kind of problems that arise when sharing data across threads are out of scope for this post, though.
Poisoning
Another idea that came to my mind is sometimes referred to as "poisoning". In this case, you don't need a master container; both of your regular containers would hold shared_ptrs to the Blocks... with a twist.
When a Block is chosen for deletion, a special flag is set on it. It becomes "poisoned", and every container should sweep such blocks before doing iteration.
If every container indeed does so, all references to the Block die and its destructor will fire properly. You're essentially communicating the command through a special value of it.
If you don't want to modify the Block class, having std::shared_ptr<std::optional<Block>> and nullyfying the optional can work just the same, except the destructor of the Block will run immediately, and not when the last structure decides to do its sweep. This might be better or worse depending on your goals and needs.
I'm using SortedDictionaries to simulate a Queue (due to some requirements that I have), and I'm calling Last() over the sorted dictionary to get the item that I need to dequeue.
I was just wondering about the performance of using a custom comparer and calling First() or keep calling Last().
After decompiling the .NET 3.5 assemblies, I found that the SortedDictionary class does have a Count property, so I'm guessing the framework just returns the item at position 0 when First is called, and the item at position [count-1] when Last is called, am I right?
No.
Since SortedDictionary does not implement IList<TValue> (which has a this[int] indexer), Last() has no choice but to iterate through the whole thing.
The Last method is an extension method in the Enumerable class. The implementation of Last first tries to cast the IEnumerable (your SortedDictionary) to IList<T>. If it can, then it uses the Count property to directly access the last element. If it can't, then it has to iterate over all elements to get to the last one. SortedDictionary doesn't implement IList<T>, so Last will iterate over all elements.
Assume that I have an Ecore-model containing a package and some classes that make reference to each other. If i create a "Dynamic Instance", Eclipse produces an XMI-file and I can instantiate some classes. Containment-relations are directly serialized to an XML-tree in the XMI (the children elements in the example). But if I instantiate references to elements that are already contained somewhere in the tree, the Editor writes Path-Expressions like in the following, for the currentChild attribute:
<parent currentChild="//#parent/#children.1">
<children/>
<children/>
</parent>
As far as I know this is not XPath, because:
The "childrens" are elements not attributes and have not to be referenced via "#"
XPath uses the e.g., elem[1] and not elem.1 to get e.g., the second elem of a list
What is it and where can I find a information on it? I already tried to browse the EMF pages/specs but could not find it.
It's an EMF Fragment Path. The Javadoc describes it like this:
String org.eclipse.emf.ecore.InternalEObject.eURIFragmentSegment(EStructuralFeature eFeature, EObject eObject)
Returns the fragment segment that, when passed to eObjectForURIFragmentSegment, will resolve to the given object in this object's given feature.
The feature argument may be null in which case it will be deduced, if possible. The default result will be of the form:
"#feature-name[.index]"
The index is used only for many-valued features; it represents the position within the list.
Parameters:
eFeature the feature relating the given object to this object, or null.
eObject the object to be identified.
Returns:
the fragment segment that resolves to the given object in this object's given feature.