I'm trying to move list elements to the stack and back to the list again, reversing their order.
I'm having trouble with the last bit of transferring the stack back into the list.
I've been using the stack.pop(); in different ways but nothing seems to work.
I'm able to just print out the output of stack.pop so far, but I really want to be able to transfer the stack contents back into the list.
public class ReverseArray {
public static void main(String[] args) throws EmptyStackException {
// TODO Auto-generated method stub
MyLinkedList<GameEntry>myList = new MyLinkedList<>();
//populate the list
myList.addFirst(new Node<GameEntry>(new GameEntry("Marche", 313), null));
myList.addFirst(new Node<GameEntry>(new GameEntry("Apricot", 754), null));
myList.addFirst(new Node<GameEntry>(new GameEntry("Dragon", 284), null));
myList.addFirst(new Node<GameEntry>(new GameEntry("Erasure", 653), null));
//print the list
System.out.println(myList);
System.out.println();
System.out.println("New Reversed List:");
//reverse the list elements
reverse(myList);
}
public static <V> void reverse ( MyLinkedList<V> list) throws EmptyStackException{
//code to reverse goes here
NodeStack<GameEntry> stack = new NodeStack<GameEntry>();
Node<GameEntry> scores = list.getHead();
for ( int i = 0; i < list.getSize(); i++){
stack.push(scores.getElement());
scores = scores.getNext();
}
while(!stack.isEmpty()){
System.out.print(stack.pop() + " ");
}
}// end reverse
}//end main
You should keep order from the stack, so add them at the end of a new LinkedList:
while(!stack.isEmpty()){
GameEntry entry = stack.pop();
list.addLast(entry);
}
Assuming you want the list to only contain the reversed elements you have to clear the list at first. Depending on your implementation you have a clear() method or must call remove() several times until the list is empy.
Afterwards you can add code like this:
while(!stack.isEmpty()){
GameEntry entry = stack.pop();
list.addFirst(entry);
}
That way you should have the reversed order of your elements in the list.
An alternativ would be implementing the List Interface with your MyLinkedList and use the Collections.reverse().
Totally missed that the order would be the same as on the input list. Therefore you have two options:
Use a Queue instead of a Stack.
Use second Stack that gets filled with the contents of your first Stack. This may look like:
NodeStack<GameEntry> secondStack = new NodeStack<GameEntry>();
while(!stack.isEmpty()){
secondStack.push(stack.pop());
}
while(!secondStack.isEmpty()){
GameEntry entry = secondStack.pop();
list.addFirst(entry);
}
Related
I have two fields in my custom class List:
LinkedList<String> breadList;
Iterator<String> iterator.
And I've defined two methods:
showBreadList() - for displaying the contents of the list;
addInOrder() - for inserting a new element into the list (the list should be updated in such a way so that elements are maintained in sorted order).
My code:
public class List {
class LinkedListExample {
private LinkedList<String> breadList = new LinkedList<>(); // <-- Edit from the answer: public to private
Iterator<String> iterator;
public void showBreadList() {
iterator = breadList.iterator();
System.out.println("Values in breadList: ");
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
}
public void addInOrder(String bread) {
ListIterator<String> stringListIterator = breadList.listIterator();
while(stringListIterator.hasNext()) {
if(stringListIterator.next().compareTo(bread) == 0) {
} else if(stringListIterator.next().compareTo(bread) > 0) {
stringListIterator.previous();
stringListIterator.add(bread);
} else if(stringListIterator.next().compareTo(bread) < 0) {
}
}
stringListIterator.add(bread); // <-- Edit: added
}
}
public static void main(String[] args) {
List list = new List();
List.LinkedListExample lle = list.new LinkedListExample();
lle.addInOrder("Ciabatta");
lle.addInOrder("Wheat Bread");
lle.addInOrder("White Bread");
lle.addInOrder("Sourdough");
lle.addInOrder("Flatbread");
lle.showBreadList();
}
}
The list gets populated in the main() method via addInOrder().
Expected output:
Values in breadList:
Ciabatta
Flatbread
Sourdough
Wheat Bread
White Bread
Actual output:
Value in breadList:
I.e. I'm getting nothing. Can anybody give a hint on what I'm doing wrong?
Seems like the goal of your assignment is to learn how to deal with a ListIterator.
The core thing to understand about the Iterators that their cursor always occupies a position in between the elements of the list (and it might also be positioned before the first element and right after the last element). And that's the position where a new element gets inserted when you invoke ListIterator.add().
Here's a quote from the official tutorial Provided by Oracle:
Intuitively speaking, the cursor is always between two elements — the
one that would be returned by a call to previous and the one that
would be returned by a call to next. The n+1 valid index values
correspond to the n+1 gaps between elements, from the gap before the
first element to the gap after the last one. The following figure
shows the five possible cursor positions in a list containing four
elements.
In the method addInOrder() you've messed around with conditions. If fact, only one condition that would check if the next is lexicographically greater than the given string would be enough. If the next is greater we continue iteration, if not we need to move the iterator the previous position by calling previous() and then break from the loop.
Method add() will be invoked on the iterator after the loop, when iterator is the right position to insert a new element.
That's how you can fix your method:
public void addInOrder(String bread) {
ListIterator<String> iterator = breadList.listIterator();
while (iterator.hasNext()) {
String next = iterator.next();
if (next.compareTo(bread) > 0) { // if the next element is lexicographically greater than `bread`, `bread` has to be inserted before it
iterator.previous(); // moving to the position where the new `bread` should be inserted
break; // breaking out from the loop
}
}
iterator.add(bread); // inserting the new kind of bread
}
Example with the sample data from the question:
LinkedListExample lle = new LinkedListExample();
lle.addInOrder("Ciabatta");
lle.addInOrder("Wheat Bread");
lle.addInOrder("White Bread");
lle.addInOrder("Sourdough");
lle.addInOrder("Flatbread");
lle.showBreadList();
Output:
Ciabatta
Flatbread
Sourdough
Wheat Bread
White Bread
I'm having so much trouble with a program I'm working.
The program is supposed to print out the elements of an ordered linked list (as in there are no setters available for the list) in alphabetical order. Here's what I have:
GOrderedList is the node, Event is the value. I had the idea to attempt to find the words and place them in an arraylist alphabetically.
public static ArrayList <String> sortEvents (GOrderedList <Event> C){
//create arraylist
ArrayList <String> sortedList = new ArrayList <String>();
while (C.getNext()!=null){
GOrderedList <Event> first = C.getNext();
String highest = first.getValue().getname();
while (first.getNext()!=null){
if (first.getNext().getValue().getname().compareTo(highest)<0){
highest=C.getNext().getValue().getname();
}
first=first.getNext();
}
sortedList.add(highest);
C = C.getNext();
}
This is producing the list -which is encouraging - but it is out of order. I had the idea of placing the elements in the new ArrayList in alphabetical order. I could place the items in the ArrayList and then sort it, but I would rather not do that.
You can use the comparator to sort it .Like below.
public static ArrayList<String> sortEvents(GOrderedList<Event> C) {
// create arraylist
ArrayList<String> sortedList = new ArrayList<String>();
while (true) {
GOrderedList<Event> first = C.getNext();
if (first == null) {
break;
}
String highest = first.getValue().getname();
sortedList .add(highest);
}
Collections.sort(sortedList , new Comparator<String>() {
public int compare(String f1, String f2) {
return f1.toString().compareTo(f2.toString());
}
});
return sortedList ;
};
There are a few issues with the code:
Calling getNext() in the while loop will increment and skip a value each time. You probably need to call a hasNext() method.
Each iteration of the outer loop needs to add its element in the proper position. As written, the value added is always going to be at the end.
As previously mentioned there are standard ways to do this, but my assumption is that you need to do this as an exercise. If not, use a Comparator. String's natural comparison may give you exactly what you want.
How would I go about writing an implementation of push for the stack ADT using list ADT? Assuming i'm pushing to the top of stack, would I have to create a temp list and do something to add the previous head to the tail?
private someList<E> stack;
public void push(E element){
stack.add(element);
}
//another file
public someList<E> add(E newHead){
return new someList<E>(newHead, this);
}
What is important in the implementation of the stack ADT, is where you are going to add the new elements you push and where you are going to delete elements you pop. Obviously push(someElement); pop(); should leave the stack unchanged.
So we have 2 choices, adding/removing elements at the end of the list or in the front.
public void push(E element){
stack.add(element);
}
You've chosen to add/remove them at the end of the list.
I don't know what the add method has to do, however if it returns a new someList which represents a/the new stack, then the private stack field should get this newly created stack assigned!
Note that if the purpose of add is to change the current head (replace current TOS (= Top Of Stack) by this one), then you could simply write it as follow
public someList<E> add(E newHead){
pop(); // remove TOS
push(newHead); // Add newHead as the new TOS
return this.stack;
}
I've implemented the stack ADT for String's. I leave it as a simple exercise to change it to your needs (using someList instead of List and using generics).
public class Stack {
private List<String> stack = new ArrayList<String>();
public void push(String element){
stack.add(element);
}
public List<String> add(String newHead){
stack = new ArrayList<String>(stack); // you should do "stack = new someList<E>(newHead, this);"
return stack; // return the new stack
}
public String pop() {
String res = stack.get(stack.size() - 1);
stack.remove(stack.size() - 1); //
return res;
}
public void printStack() {
System.out.println("TOS (Top Of Stack)");
for(int i = stack.size() - 1; i >= 0; i--)
System.out.println(stack.get(i));
System.out.println("EOS (End Of Stack)");
}
}
// Test it
...
String a = "a", b = "b";
Stack stck = new Stack();
stck.push(a);
stck.push(b);
stck.push(b);
stck.push(a);
stck.pop();
stck.printStack();
...
This is how the stack is changing during the test case.
TOS (Top Of Stack)
a ---> b ---> b ---> a ---> b
a b b b
a b a
a
EOS (End Of Stack)
Note that in this implementation of the stack ADT we are pushing/popping elements from the stack by adding/removing elements from the list's tail (more precisely arrayList). Which is ideal for use with java's arrayList because adding an element to the tail of the list, or removing the last element, is in O(1).
Methods specifying insertion position have to copy all array elements to the right from insertion
(Source)
You will have to check if the same holds when using your own someList implementation. However, if adding an element to the tail of the list (or removing the last element) requires you to traverse the whole list (which is the case for e.g. a single linked list, hence O(n)), then adding/removing the first element should be in O(1).
In that case you should change the stack ADT's implementation so that the front of someList is now representing the TOS and the tail of the list is representing the end of the stack. Hence push/pop will then add/remove elements at the front of the list.
EDIT : You could implement a count method :
By explicitly remembering how many elements are on the stack (i.e. you have a size field that you increment for every push() and decrement for every successful pop() (i.e. for every pop() when size > 0 then decrement size).
By relying on the size() method of the ArrayList that is used to represent the stack.
Hence a possible implementation
public class Stack {
private List<String> stack = new ArrayList<String>();
...
public int count() {
return stack.size();
}
}
I have two lists one is feature and has a placement number based on which i insert data in sorted list e.g if placement number is 5 data will be added in 5th position .i want to add data at 5th postion and to move data which was at 5th position to next index but in my case it just replace data at 5th position not move current data to next position
for (int i = 0; i < featuredList.size(); i++) {
int n = featuredList.get(i).getPlacementNumber().intValue();
if (n < sortedList.size()) {
sortedList.add(n, featuredList.get(i));
} else {
sortedList.add(featuredList.get(i));
}
}
You should use ArrayList, from add(int index, E element)
Inserts the specified element at the specified position in this list. Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices).
Make your sortedList as ArrayList:
List<YourType> sortedList= new ArrayList<YourType>();
See the example http://ideone.com/L6hpsf
String s1 = "s1";
String s2 = "s2";
String s3 = "s3";
List<String> list = new ArrayList<String>();
list.add(s1);
list.add(s3);
list.add(1, s2);
System.out.println(list);
Output: [s1, s2, s3]
Try to use LinkedList to insertion or deletion between list for better performance then ArrayList :
private LinkedList<String> linkedList = new LinkedList<String>();
linkedList.add("1");
linkedList.add("2");
linkedList.add("3");
linkedList.add("4");
linkedList.add("5");
// insertion at 3 position
linkedList.add(2,"6");
Another example which may give you some clue and even easy to run :)
import java.util.ArrayList;
public class Alisttest {
public static void main(String[] args) {
ArrayList a = new ArrayList();
a.add("1");
a.add("2");
a.add("3");
a.add("4");
System.out.println("a=> "+a.get(2));
a.add(2, "Pankaj");
System.out.println("a=> "+a.get(2));
System.out.println();
System.out.println("a=> "+a);
}
}
public static void main(String [] args){
Scanner input = new Scanner(System.in);
System.out.println("Enter some numbers (all on one line, separated by spaces):");
String line = input.nextLine();
String[] numbers = line.split(" +");
ArrayList<Integer> a = new ArrayList<Integer>();
for(int i=0; i<numbers.length; i++)
a.add(new Integer(numbers[i]));
System.out.println("The numbers are stored in an ArrayList");
System.out.println("The ArrayList is "+a);
System.out.print("\nEnter a number: ");
int p = input.nextInt();
System.out.println(removeNumber(a,p));
System.out.println(removeNumber2(a,p));
}
public static <T> ArrayList<T> removeNumber(ArrayList<T> a, Integer e)
{
ArrayList<T> b = new ArrayList<T>();
for(int i = 0; i< a.size();i++)
{
if (a.get(i).equals(e))
a.remove(e);
}
return a;
}
if ex.value = 4, I want to remove 4 from the arrayList. If my arraylist contains [5,12,4,16,4], I want to remove the first occurence of four from it, and save it to another arraylist.
Don't want to use Iterators
Without using an iterator, here's what you could do to fix your code :
for(int i = 0; i< a.size();i++) {
if (a.get(i).equals(e.value)) {
a.remove(e.value);
i--;
}
}
Beyond the change of == to equals, you have to decrement i whenever you remove an element from the ArrayList. The reason for that is that removing the ith element from an ArrayList decreases the indices of all the elements that follow it by one. Therefore, the i+1th element will become the new ith element, so you must decrement i in order not to skip the next element.
EDIT : For some reason I was sure you wanted to remove all occurences of the number from the list, and not just the first one. If you only want to remove one element from the list, you don't have to worry about iterating over the rest of the list after removing that element.
You cannot iterate over an ArrayList and modify it at the same time, without an Iterator
Do like this :
for(Iterator<T> i = a.iterator(); i.hasNext();)
{
if (i.next().equals(e.value))
{
i.remove();
}
}
BTW, your b ArrayList is useless.
Along with the suggestion of using iterators, you should not be using the operator == which checks for reference equality. This will always be false in your scenario. You want to use the equals method instead which checks for value equality.
if (a.get(i).equals((Integer)e.value)))
You don't need to iterate through the list, either with an iterator or an index. ArrayList has a remove method that searches for and removes an element, and returns true or false depending on whether it found an element to remove. So you can say
while (true) {
boolean found = a.remove(e.value);
if (!found) {
break;
}
}
or
boolean found;
do {
found = a.remove(e.value);
} while(found);
or if you value compactness over readability,
do { } while(a.remove(e.value));
Note that a.remove(e), as you have in your original code, won't work at all. The ArrayList is an ArrayList of Integer, but e is an EX6. Thus, a.remove(e) won't find e in the list at all, since it isn't even the correct type. It should compile fine, since remove is defined to allow any Object as a parameter, but it will never find anything (since the equals method of Integer always returns false for a non-Integer).