I'll write down the whole problem first.
A ring is a collection of items that has a reference to a current item. An operation -- let's call it advance--moves the reference to the next item in the collection. When the reference reaches the last item, the next advance operation will move the reference back to the first item. A ring also has operations to get the current item, add an item, and remove an item. The details of where an item is added and which one is removed are up to you.
Design an ADT(Abstract Data Type) to represent a ring of objects. Specify each operation by stating its purpose, by describing its parameters, and by writing a pseudocode version of its header. Then write a Java interface for a ring's methods. Include javadoc-style comments in your code.
So is it saying the Ring is like a class with operation that can move items by using a reference variable like T = items? And Advance would change T to represent a different item each time it's being called? Something like in UML format....
ADT: Ring
+advance(): T // move T to next item in collection and if T reaches last item, move T back to the first item.
+getCurrItem(): T // return item that T reference.
+addItem(item T): void // add an item in for T, No return.
+removeItem(Item: T): boolean // remove item that T reference and return true | false if it succeed or not.
Am I on the right track or am I supposed to do something else?
That looks like a good start to me. Now you have to work on designing the ADT and how you suppose you will store items and reference the end to the beginning. This is a data abstractions problem, and you can approach the implementation in several ways, but it's up to you to design it in an efficient way.
Related
I'm trying to write a code for a method which has certain conditions which needs to be met. I believe that I need to use methods from a different class to meet the conditions. I've done the last 2 conditions but I have got no clue on how to go about the others because I do need to access methods from a different class.
It seems like using the shtlCode, you can obtain the proper Shuttle instance from your shuttleMap, like so:
public boolean canTravel(int pCardId, String shtlCode)
{
Shuttle shuttle = shuttleMap.get(shtlCode);
...
Once you have the Shuttle, you can then find the Asteroid it's currently on:
Asteroid currentShuttleAsteroid = shuttle.getSourceAsteroid();
Having these two objects, it's up to you to ensure the conditions have been properly met. (And also, to ensure that your shuttleMap contains a Shuttle with the code specified, etc.)
As Craig suggested above, keep the Shuttle that you fetched from the hashmap. You will need it to implement most of the remaining checks.
canTravel is given a card id, but is going to need the PearlCard itself. But where to get it from? Three possibilities:
The caller can pass a PearlCard into canTravel instead of the integer ID, if it has it.
canTravel could search for a PearlCard with the matching ID in the source asteroid's list of PearlCards. (And if it's not in there, then you can't travel anyway.)
Or you may want to add a HashList of all PearlCards to your program, similar to shuttleMap.
Then get the shuttle's destination asteroid and see if has room for one more PearlCard (compare PearlCard list's length to the asteroid's capacity). Also check to see if the card has enough credit and rating for that asteroid. (You didn't show PearlCard class so I don't know the exact code, but I'm guessing you'll have no trouble with that part.)
Note: your current code seems to have at least one bug. canTravel searches the asteroid list for the card ID. Like I said above you will need to get the card from somewhere, but it's not going to be in asteroidList.
Let me ask this question taking Java code mentioned in the query link.
In the same query link, a supplementary answer says: "In general, we need to separate List and Node classes, your List should have an head and your Node will have item and next pointer."
In addition, my class lecture says, there are two reasons for separating List and Node class.
Reason 1:
Assume user X and user Y are pointing to the first List_Node in that list
After adding soap item by user X in the shopping list, below is the situation,
So, User Y is inconsistent with this situation.
Reason 2:
Handling empty list.
user X pointing to an empty list, that mean X is null.
X.nth(1); //Null pointer exception
My question:
Reason_1 could have been handled by inserting new node after last node. Reason_2 could have been handled, as part of error check in the code.
So, Why exactly we need to separate Node and List class?
Note: Java code has item of type intinstead of type Object that can accommodate strings. I did not want to change this code again.
Reason_1 could have been handled by inserting new node after last node.
But that is changing the problem. Lists are ordered. Adding an element before an existing element or after an existing element are different operations. The data structure must be able to handle both operations, otherwise it is not a proper list.
Reason_2 could have been handled, as part of error check in the code.
That wouldn't work. The code of your list abstraction can't handle the NPE. If you attempt to call x.nth(1) and x is null, the exception is thrown before you get into any of the code that implements the list. Therefore, the (hypothetical) error handling in the list code cannot be executed. (Java exception handling doesn't work like that ...)
And as you correctly point out in your comment, forcing code that uses a list to handle empty lists as a special case would be bad list API design.
In short, both of the reasons stated are valid. (IMO)
Here are some very good reasons:
Separate implementation from interface. Perhaps in the future someone will find a new perfectly good implementation of your life involving a row of carrier pigeons moving elements around. Should your client code have to update everything with methods flapWings and rewardPigeon instead of manipulating nodes? No! (More realistically, Java offers ArrayList and LinkedList IIRC).
It makes more sense. list.reverse() makes sense. node.reverse()... what? Does this change every other node recursively or not?
Speaking of that reverse method, if you implement it right now you can implement it in O(N). You know if you have an int orientation; that is 1 or -1, you can implement it in O(1)? But all subsequent operations need to use that bit, so it's a meta-node operation, not a node operation.
Empty lists are possible. Empty nodes don't make sense. This is your (2). Imagine this: I am a client of your software. You have list == node. A rival vendor offers separation. You say "oh it works fine just add an error check in your code." Your rival does not. Who do I buy from? This is a thought experiment meant to convince you these really are different, and the former does have a defect.
Let's say we have an array list of objects ObjArray.
What is the most efficient way for that object to locate itself within the list, and remove itself from the list?
The way I tend to use is this:
Every object in the list has an ID that corresponds to its place in the list
When object.remove() is called, the object simply simply calls ObjArray.remove(ID).
ObjArray is parsed from index ID upwards calling ObjArray.get(i).ID--. This sets all objects above the removed object to the right ID.
The other method is of course simply parsing ObjArray until a object match is found.
So, is there a better way of doing this? ArrayList is not necessary, if a HashMap or LinkedList can be used to do things better, that's just as good.
More information as requested.
Objects contain information as to where they need to be drawn on screen, and what image is to be drawn. The paint function of the main JPanel is called by a timer. The paint function loops through the list ObjArray and calls the the object's draw function (Obj.draw(Graphics g)).
Objects may be added or removed by clicking.
When an object is removed, it need to remove itself from the ObjArray list. I have stated the two methods that I can think of in the first part.
I would like to know if anyone knows of a more efficient way of doing this.
In short:
What's the most efficient way for an item to find/know its position in a list
Efficient in terms of code:
list.remove(this);
The object must be given a reference to the list of course.
Efficient in terms of performance would require a small redesign, probably involving a Map, but is beyond the scope of this question.
Usethe List's indexOf to get the ID. Drop your idea of an ID for each object._
I got a problem here, implementing a Sorted Doubly Linked List of first and last names.
Add a field to each link that indicates the alphabetically next first name; the existing next link is used to indicate the alphabetically next last name. You will also need a second root link for the list - the existing root link indicates the alphabetically first last name, and you will need one indicating the alphabetically first first name. Note that you will still only have one link object for each name entered in the list.
Having done this, make any necessary changes to your insert, lookup, and delete methods so that both interleaved lists are maintained. Also update the runtime estimates as required to remain accurate.
Finally, add a second lookup method that takes in a first name and returns all full names including that first name, and a second display method that prints the list of names out alphabetically by first name. Make sure you give runtime estimates for these methods as well.
And I am at a complete loss as how to do this. I already created a single linked list, with a first and last name, but that's as far as I was able to get.
Any Help would be great :D
Thank you.
Create a Link Class that has two link fields (nextFirstName, nextLastName) and a field for the Name Object.
On insert, first search the Link object that comes before (LastName) this new one and insert it after that using the nextLastName field. Then do the same with the FirstName, using the nextFirstName field as the link.
?????
profit!
This does smell a lot like homework :)
Because you have already implemented a Singly Linked List, expanding to a doubly linked list shouldn't be too difficult. You already have references going forward (see picture below). Now you need to add references going backward as well. In addition, note the blue lines in the picture below. Add additional references for the spelling properties. So each node will have the variables:
private Node NextFirstName;
private Node PreviousFirstName;
private Node NextLastName;
private Node PreviousLastName;
You do NOT need backward-references! The task asks for something like 2 single-linked Lists, that use the same objects as entrys. Every object has two links: one to the next item in list A, and one to the next item in list B.
I have an ArrayList to store some data, but whenever I remove an item from the list, the size does not decrease, even when I call ArrayList.trimToSize(). This is causing me nullPointerExceptions.
How can I remove a single item from an ArrayList and have the list's size() shrink accordingly?
EDIT: All right, here's the code. Here's a bit of background you'll need to know, since I can't post all the code. I have an ArrayList called _dataHeap and a HashMap called _dataMap. The ArrayList is a binary Heap containing a "findable" object, which has a Key. The HashMap bind from a Key to the index of the object in the ArrayList. This is so an item in the queue can be found by item using the HashMap or by index using ArrayList. The Key can be any Object, as long as it is unique for every item in the queue.
I've debugged this line by line, and the Heap contains the object, even down to the Hashcode. The problem is, the Object is never being removed from the ArrayList. This must mean that _dataMap.get(element.getKey()) is not pointing to where it should. I've checked it though, I used a test object outside of my implementation that maps from a String to a custom object with String as a Key.
I make one object, with String "one" as its key. I insert it, then try to remove it. I've stepped through this, and everything checks out, except one thing: The object is never removed from the queue. It's got the same Hashcode, the same Key, everything. It gets removed from the map just fine, but not from the ArrayList.
Here's the remove method:
public T remove(T element) {
//We'll need this data to return the proper value
T t = _dataHeap.get(_dataMap.get(element.getKey()));
/*
* this Swap() call is used to swap our target with the end
* of the arraylist. This means that whenever we remove it,
* we don't have a change in indexes of the other nodes.
* After that, we downHeapify() to fix the whole graph back
* to it's functional state.
*/
swap(_dataMap.get(element.getKey()),length()-1);
//Remove from the Heap
_dataHeap.remove(_dataMap.get(element.getKey()));
_dataHeap.trimToSize();
//Remove from the Map
_dataMap.remove(element.getKey());
downHeapify();
return t;
I hope this gives you a better idea of what I'm doing wrong.
EDIT THE SECOND: Holy crap I finally fixed it! I pulled the _dataHeap.get(element.index) into it's own variable. That solved EVERYTHING!
As Bemace said, check if remove works as you intend. I'd bet money that your equals() method on the object you're composing doesn't work how you'd expect it to, because you did not override it.
Furthermore, after you override equals, take care to also override hashCode. It'll save you a SO question when your object doesn't work with HashMaps. :)
A tip: Look into using JUnit. It will blow these little errors right out of the water, making it obvious to you when something's not working how you'd hope. It's very hard to ignore a bright red spot on your beautiful green bar.
Sounds to me like you're not actually removing anything. What's the return value of your remove call?
If you're using remove(int) the return value should be non-null. If using remove(Object), the result should be true. Otherwise you haven't actually removed anything. Attempting to remove an element which doesn't exist is not an error, just returns null or false.