Reversing an ArrayList (Understanding the code) - java

I found an exercise in a book that adds some money into an ArrayList, and then reverses them. I know we can easily use Collection.reverse(), which is what my textbook shows, but I found another cool solution online that I am trying to understand but having trouble with.
Heres the code:
class Purse {
private ArrayList<String> coins = new ArrayList<String>();
public void addCoin(String coinName) {
coins.add(coinName);
}
public void reverse() {
for(int start = 0, end = coins.size() - 1; start < coins.size() / 2; start++, end--) {
swap(start,end,coins);
}
}
private void swap(int starting, int ending, List aList) {
Object temp = aList.set(starting, aList.get(ending));
aList.set(ending,temp);
}
public String toString() {
return "Purse: " + coins;
}
}
public class PurseDemo {
public static void main(String [] args) {
Purse purseObj = new Purse();
purseObj.addCoin("Quarter");
purseObj.addCoin("Dime");
purseObj.addCoin("Penny");
purseObj.addCoin("Nickel");
System.out.println(purseObj);
purseObj.reverse();
System.out.println(purseObj);
}
}
Here is where my confusion is:
Object temp = aList.set(starting,aList.get(ending));
aList.set(ending,temp);
First of all, I think I get the idea of this. However, this is my first time seeing the Object keyword. What I don't really get is what temp actually represents ( I got this code off online, in my book they havent introduced this keyword Object yet)
Here are my thoughts on an example iteration
Suppose our arrayList has
[Quarter,Dime,Penny,Nickel]
According to Object temp = aList.set(starting,aList.get(ending));
We take the the first spot in the ArrayList Quarter and put the value of nickel in there. So we get the ArrayList
[Nickel,Dime,Penny,Nickel]
Now I'm kind of confused.. When I system.out.println(temp), it tells me the values are Quarter and Dime. But why? Can someone go through an example iteration with me?
AFTER READING ANSWER
[Quarter,Dime,Penny,Nickel]
Nickel replaces Quarter, thus temp is Quarter. So we add Quarter to the end
I.E we get
Quarter,Dime,Penny,Quarter
Wait.. But where did our nickel go?!

The set() method returns the object that is being displaced by the new object. The first line
Object temp = aList.set(starting,aList.get(ending));
is the same as:
Object temp = aList.get(starting);
aList.set(starting, aList.get(ending));
You could actually do it without the temp variable, in one line:
aList.set(ending, aList.set(starting, aList.get(ending)));

The swap method can be translated into its "usual form":
Object temp = aList.get(starting);
aList.set(starting, aList.get(ending));
aList.set(ending, temp);
All the code you found does is combine the first two lines because List.set promises to return the replaced value.
Now let's see your example, where aList initially is [Quarter,Dime,Penny,Nickel], and starting is 0 and ending is 3.
Object temp = aList.get(starting);, now temp is Quarter.
aList.set(starting, aList.get(ending));, now aList is [Nickel,Dime,Penny,Nickel].
At last, aList.set(ending, temp);, sets the last element of aList to Quarter: [Nickel,Dime,Penny,Quarter]

Related

Using an array in a recursive algorithm to find combinations

The idea is if i am at a certain stair i can either go one step down or two so if am at stair 3 i can go down 1 1 1 or 2 1 for example. My code should print all the possibilities. The error I get is that I can't convert the add function to an array (since the add method is a boolean). What is wrong with this algorithm?
public class Stairs {
public static void staircase (int height ){
ArrayList<Integer> Array = null;
explore (height,Array);
}
public static void explore(int objheight,ArrayList<Integer>Array){
int intialheight = 0;
if (intialheight == objheight){
Array.toString();
}
else{ if (objheight > intialheight ){
explore(objheight-2,Array.add(2));
explore(objheight-1,Array.add(1));
}
}
after your feedback I am getting an empty output
import java.lang.reflect.Array;
import java.util.ArrayList;
public class Stairs {
public static void staircase (int height ){
ArrayList<Integer> Array = new ArrayList<Integer>();
explore (height,Array);
}
public static void explore(int objheight,ArrayList<Integer>Array){
int intialheight = 0;
if (intialheight == objheight){
Array.toString();
}
else{ if (objheight > intialheight ){
Array.add(2);
explore(objheight-2,Array);
Array.add(1);
explore(objheight-1,Array);
}
}}
public static void main (String args[]){
staircase(3);
}
}
The method add(E e) in ArrayList returns true upon appending the element e passed as a parameter to the end of the ArrayList.
Your method, explore(int objHeight, ArrayList<Integer> Array) does not accept a boolean for its second parameter. Yet, in that same method, explore, you are recursively calling explore and passing in a boolean to the method.
The following code should be modified to first invoke the add method of Array and then pass Array to the explore method.
Before:
explore(objheight-2,Array.add(2)); This code is passing parameters int and boolean to the explore method, which is not the parameters it accepts. You should instead attempt the following.
After:
Array.add(2);
explore(objheight-2,Array); This code first adds 2 to the Array and then passes the Array to the explore method without invoking any further methods on the Array object.
You will also need to do this for the next line of code, where you have explore(objheight-1,Array.add(1));.
Edit: Upon further examination of the code, I discovered another (sooner) error that occurs. A NullPointerException will occur each time the program runs:
ArrayList<Integer> Array = null;
explore (height,Array);
Then inside the explore method, different methods on Array are invoked, despite Array always being null:
Array.toString();, Array.add(2) and Array.add(1).
The Array object must be initialized inside of either the staircase or explore methods.
ArrayList<Integer> Array = new ArrayList<Integer>(); or ArrayList<Integer> Array = null;
Array = new ArrayList<Integer>();

Java, return a linkedlist from a linkedlist parameter

I am trying to create a method which returns the place values of any two digits in a list that sum to zero. Where I am getting stuck is: creating the return method type, choosing the appropriate parameter to pass, and creating an empty list which holds the values to return.
Any help would be greatly appreciated!!
public class TwoSums {
public LinkedList<Integer> sum_values(LinkedList<Integer> input){
(Above) I am trying (but not sure how) to return a linked list from the method. I want the parameter to be a list with values like {3,-3,0,1}. I am also unsure of what the return type should be here.
int iterator = 0;
int scanner = 0;
LinkedList positions = new LinkedList<Integer>();
(Above) I am trying to create an empty list which I can push the place values of the parameter into, if they sum to zero
while(iterator<input.length){
if (iterator + scanner !=0){
scanner ++;}
else if (iterator + scanner ==0){
//push iterator and scanner values to the linkedlist
This is probably your homework, so I will just give you some guiding thoughts; I wont do the work for you!
First of all, the return type. Thing is: you can't just return single numbers. Because, you are interested in pairs of numbers. Thus you need some class like
public class IndexPair {
private final int firstIndex;
private final int secondIndex;
public IndexPair(int first, int second) { this.firstIndex = first ...
and then your method can simply return a List<IndexPair> object. Note: if you are serious here, you would want to override the equals method for example; in order to allow for easy comparison of IndexPair objects.
And of course: Java already knows some Pair classes which could be used here; instead of inventing your own thing.
The other problem: finding those pairs. A naive solution would be:
List<IndexPair> results = new ArrayList<>();
for (int firstIndex = 0; firstIndex < input.size(); firstIndex++) {
for (int secondIndex = firstIndex+1; secondIndex < input.size(); secondIndex++) {
if (input.get(firstIndex) + input.get(secondIndex) == 0) {
results.add(new IndexPair(firstIndex, secondIndex));
As said; the above is meant to get you going. There might be some typos or subtle bugs in that code. Take it as inspiration and work with it until it does what you need!
Edit: calling your method is as as
List<IndexPair> pairs = sum_values(Arrays.asList(-3, 3, 0, 0))
for example. But please understand: that is really basic stuff. Just do some reading around Lists and arrays. Those things have been documented many many times.

Depth First Search is causing a StackOverFlowError

I have an assignment were I have to create run a depth first search through a directed graph, and return the traversal as a linked list. I believe the code for the DFS is correct as it seems to match up with the text book, and as I walk through the steps it makes sense. If I print it out as each vertex gets marked, it keeps printer over and over causing the stack overflow error.
private static boolean[] marked;
private static LinkedList<Integer> ret;
public static LinkedList<Integer> dfs(Digraph g, int s) {
marked = new boolean[g.V()];
ret = new LinkedList<>();
marked[s] = true;
System.out.print(s);
ret.add(s);
for (int i : g.adj(s)) {
if (!marked[i]) {
dfs(g, i);
}
}
return ret;
}
My guess would be the boolean[] marked is reseting every time I call dfs. I tried putting that outside the method but because the method is static and I can't change it(given the assignment parameters), I was getting a static-non static issue which I'm not quite sure how to fix.
Yup, your issue was indeed because the boolean was being reset in a sense. The resetting was happening in this line:
marked = new boolean[g.V()];
On this line, you are creating a new boolean array in the new function call, which is distinct from the original array . Then you are checking the new array which does not contain the changes from the old array.
I would recommend that you create a wrapper function that initializes the dfs process, and then pass the array into each call of your dfs function.
If you do not want to add extra parameters, just create a static variable as such outside of the method:
private static boolean[] marked;
Then initialize it when appropriate

Insert in a sorted Array-Queue

I'm working on sorted Queues like a Priority Queue. I already did it with a List, and it already worked great. Now I'd like to do it with a array. But I have a little logical Problem with add a new Element and insert it into the sorted array.
The final output should be like that:
Priority: 5 Value: x
Priority: 4 Value: iso
.... (and so on)
So the Element with the highest Priorithy should be on index = 0.
I just don't know (and yes I know it's really simply to switch it, but I just can't do it :/) how to do it...
I already tried a few things but I'm stuck... :/ can please anyone help?
Here's my code:
public class Queue {
private QueueElem[] a;
public Queue(int capacity)
{
QueueElem[] tempQueue = new QueueElem[capacity];
a= tempQueue;
}
public void enqueue(int p, String v)
{
QueueElem neu = new QueueElem(p,v);
int i=0;
while(i<a.length)
{
if (a[i] == null)
{
a[i] = neu;
break;
}
i++;
}
}
public void writeQueue()
{
int i=0;
while((i< a.length) && (a[i] != null))
{
System.out.println("Priority: " + a[i].priority + " Value: " + a[i].value);
i++;
}
}
public static void main(String args[])
{
Queue neu = new Queue(10);
neu.enqueue(4,"iso");
neu.enqueue(2,"abc");
neu.enqueue(5,"x");
neu.enqueue(1,"abc");
neu.enqueue(4,"bap");
neu.enqueue(2,"xvf");
neu.enqueue(4,"buep");
}
}//end class Queue
class QueueElem {
int priority;
String value = new String();
public QueueElem(){ }
public QueueElem(int p, String v)
{
this.priority = p;
this.value = v;
}
public int getPrio()
{
return this.priority;
}
public String getValue()
{
return this.value;
}
}
It would be better if you interpreted your array as a max-heap. That is the typical way to implement priority queue.
What you're looking for, if you're trying to maintain a sorted array for your priority queue, is to implement insertion sort (sort of; you don't have an unsorted array to start with. You have an empty array that you simply add to, while maintaining a sorted order). Every time you insert a new element, you will iterate through the array to find the correct spot and then insert it there, after shifting the elment currently at that spot, and everything after it one spot down. Note that this is not as performant as implementing this using a heap, since at worst you have O(n) performance every time you insert, whereas with a heap you have O(logn).
I don't understand why anyone would want to work with raw arrays... especially now that you have implemented it with a List.
If you want to see how to insert an element in a raw array, look in the code of ArrayList, since underneath it uses a raw array. You'll have to move all the elements to right of the insertion point, which you could copy in a loop, or by using System.arraycopy(). But the nastiest part is that you will likely have to create a new array since the array size increases by one when you add an element (it depends if you are using an array that has exactly the size of your data, or a larger array, as is done in ArrayList).

Creating a remove() method to remove an item from an arraylist (Java)

I have 2 classes Student class and StudentTest class. In my Student class I need to write a method called remove(int ID) to remove a student with a specific ID, from an arraylist. The method is called by the main() method in StudentTest class. the code looks like this:
public class Student {
private final int size = 12; //max. size
private int [] ID = new int [size]; //the student's id number
private String [] name = new String [size]; //the student's name
private double [] tuition = new double [size];
int position= 0; //position to add data
//an add() method goes here, but is not the case of my question so I'm emitting it
//Here is the remove() to remove a student given their ID number
public void remove(int ID){
for(int i=0; i<size ; i++)
if (ID[i].equals(ID)
{
remove(i);
return true;
}
return false;
}//remove() :this method is so wrong I know, but I've been trying so many different things and its just driving me nutts!
//a method goes here to display student info.
} //end Student class
//below is my StudentTest class which will be calling the remove() method
public class StudentTest extends Student {
//main
public static void main(String args[]){
Student stuList = new Student();
stuList.add(1234, "Jane Jane", 23000);
stuList.add(4321, "Billy Bill", 15500);
//2 students are added to the list: in this order; (ID, "Name", Tuition)
//now this main program calls remove(), to remove a student by ID
stuList.remove(1234);
//rest of code entails displaying the new list and so on
}//main()
}// StudentTest class
Now. My remove method desperately needs help. I've studied the ArrayList class and its methods. but simply writing stuList.remove() doesn't work at all. I also tried the iterator method (I got lost on that one). Please guide me in the right direction ..thanks!
I would give up on solving the immediate issue and return to the design and get the OOP right, starting with
1) Student, should that be a collection or does it represent a single student.
Is the an assignment in an introduction programming course?
I dont see why you have to have the StudentID, Name and Tuition as arrays, the student class should define a "Student" not multiple students.
Class 1 - Student
Student
{
int ID;
string Name;
double Tution;
}
Class 2 - StudentManager
StudentManager
{
Student ListOfStudents;
AddStudent();
RemoveStudent();
}
EDIT:
The Student Class represents one student, and the features of that student such as Name, and Tuition, the StudentManager is used for interacting with Students objects adding and removing them from Lists etc, as opposed to having 3 arrays containing one piece of the students information and trying to update them all, this is poor design and its good to learn to avoid this kind of thing early on.
When I was learning OOP before I even started coding I used to identify possible objects that could be translated into Classes, discovered what properties they could have and how they would interact with other Objects.
You will see that no-one will post a solution to your problem here as this is homework, but we can try and help you understand how you can solve your problem.
You have 3 arrays and an int position to store the position to add data. If you remove one student you have to:
1) find it's position in the array, say r is the position to remove (it can be between 0 and position-1)
2) decrease the position (position = position - 1) because now your list will be shorter.
3) replace, for all 3 arrays, element with position r with the one located at position r+1, now you have lost the element at position r and you have twice the one that is located at r+1.
4)replace r+1 with r+2 and so on until you have replaced position-1 with position (the new value of position)
If you have problems implementing this show us some code and ask for help again...
EDIT: to respond to your comments:
You have 7 elements numbered 0 to 6, position is 7 as it is where to insert the next value, you want to remove the one numbered 4 (r=4). Here is a simpler solution but it will change the order of the list:
position = position - 1; // now position is 6
array[r] = array[position]; // now element at position 4 was replaced with the one at the end of the array, which is still there by the way. Do this for all the 3 arrays...
That's it...
The problem in your code is that your remove() method calls itself recursively infinetly to die with a StackOverflow
public void remove(int ID){
boolean found = false;
int i = 0;
for(i=0; i<size ; i++)
if (ID[i].equals(ID)
{
found = true;
break;
}
if (found) {
// remove the item and push all subsequent items to save space.
while (i < size - 1; i++) {
ID[i] = ID[i + 1];
}
}
return found;
}

Categories

Resources