Shifting an ArrayList - java

I have written a SortedIntList class that has an add and get method.
I am calling the following four methods:
SortedIntList mySortedIntList = new SortedIntList();
mySortedIntList.add(9);
mySortedIntList.add(7);
System.out.println("0 is :"+mySortedIntList.get(0));
System.out.println("1 is :"+mySortedIntList.get(1));
My get and add methods looks like this:
public void add(Integer newValue) {
int position = 0;
while(position < list.size()){
int currentPosValue = list.get(position);
if(newValue <= currentPosValue){
for(int i=list.size()-1; i>=position; i--){
int toBeShifted = list.get(i);
list.set(i+1, toBeShifted);
}
list.set(position, newValue);
return;
}
position++;
}
list.add(newValue);
}
public int get(int i) throws IndexOutOfBoundsException {
// Postcondition: If i < 0 or i >= size() throws
// IndexOutOfBoundsException, otherwise returns the value
// at position i of this IntList
if (i < 0 || i >= list.size()) {
throw new IndexOutOfBoundsException("SortedIntList.get");
} else {
return ((Integer) list.get(i)).intValue();
}
}
public int get(int i) throws IndexOutOfBoundsException {
// Postcondition: If i < 0 or i >= size() throws
// IndexOutOfBoundsException, otherwise returns the value
// at position i of this IntList
if (i < 0 || i >= list.size()) {
throw new IndexOutOfBoundsException("SortedIntList.get");
} else {
return ((Integer) list.get(i)).intValue();
}
}
I have written it out on paper, and it seems logical, but the code blows up on:
System.out.println("1 is :"+mySortedIntList.get(1)) line, apparently 1 is outofbounds, but I don't see how.

Reading the Java Doc helps. Apparently using set() requires there to already be a value at the position you are trying to override. I needed to use add(position, value) instead :-)

It might be easier to use the Collections.sort(), this standard Java method will sort your Collection for you. This way you don't have to deal with the sorting yourself, good luck!

I see a couple of problems.
First, list.set(i+i, toBeShifted); should probably be list.set(i+1, toBeShifted);. When you are adding 7 to the list, your list size is 1. In the for loop, you initialize i to be 0 (list size - 1). When you call list.set(i+i, toBeShifted) you are calling list.set(0, toBeShifted), and so not actually shifting the value.
Second, though you don't run into it with adding a 9 and then a 7, you will end up in an infinite while loop. You never change the value of position. If you add a 9 and then a larger number, you're hosed.

You can't use list's set() to add to a list: for example, if you try to set something at index 1 to something in a list of size 1, you'll get an IndexOutOfBoundsException.
Basically, you need to add first.

Related

Finding the largest element in an array using recursion in Java

This is what I have so far, but I'm confused on how to keep track of the index. I would change the parameters of the method, but I'm not allowed.
I can only use a loop to make another array. Those are the restrictions.
public class RecursiveFinder {
static int checkedIndex = 0;
static int largest = 0;
public static int largestElement(int[] start){
int length = start.length;
if(start[length-1] > largest){
largest = start[length-1];
int[] newArray = Arrays.copyOf(start, length-1);
largestElement(newArray);
}
else{
return largest;
}
}
/**
* #param args
*/
public static void main(String[] args) {
int[] array1 = {0,3,3643,25,252,25232,3534,25,25235,2523,2426548,765836,7475,35,547,636,367,364,355,2,5,5,5,535};
System.out.println(largestElement(array1));
int[] array2 = {1,2,3,4,5,6,7,8,9};
System.out.println(largestElement(array2));
}
}
Recursive method doesn't need to keep the largest value inside.
2 parameters method
Start to call with:
largestElement(array, array.length-1)
Here is the method:
public static int largestElement(int[] start, int index) {
if (index>0) {
return Math.max(start[index], largestElement(start, index-1))
} else {
return start[0];
}
}
The 3rd line of method is the hardest one to understand. It returns one of two elements, larges of the one of current index and of remaining elements to be checked recursively.
The condition if (index>0) is similar to while-loop. The function is called as long as the index remains positive (reaches elements in the array).
1 parameter method
This one is a bit tricky, because you have to pass the smaller array than in the previous iteration.
public static int largestElement(int[] start) {
if (start.length == 1) {
return start[0];
}
int max = largestElement(Arrays.copyOfRange(start, 1, start.length));
return start[0] > max ? start[0] : max;
}
I hope you do this for the study purposes, actually noone has a need do this in Java.
Try that for the upper class, leave the main method it's is correct.
public class dammm {
public static int largestElement(int[] start){
int largest = start[0];
for(int i = 0; i<start.length; i++) {
if(start[i] > largest){
largest = start[i];
}
}return largest;
}
If your goal is to achieve this by using recursion, this is the code that you need. It is not the most efficient and it is not the best way to deal with the problem but it is probably what you need.
public static int largestElement(int[] start){
int length = start.length;
if (start.lenght == 1){
return start[0];
} else {
int x = largestElement(Arrays.copyOf(start, length-1))
if (x > start[length-1]){
return x;
} else {
return start[length-1];
}
}
}
Imagine that you have a set of numbers you just have to compare one number with the rest of them.
For example, given the set {1,8,5} we just have to check if 5 is larger than the largest of {1,8}. In the same way you have to check if 8 is larger than the largest of {1}. In the next iteration, when the set one have one value, you know that that value is the bigger of the set.
So, you go back to the previous level and check if the returned value (1) is larger than 8. The result (8) is returned to the previous level and is checked against 5. The conclusion is that 8 is the larger value
One parameter, no copying. Tricky thing is, we need to pass a smaller array to the same method. So a global variable is required.
// Number of elements checked so far.
private static int current = -1;
// returns the largest element.
// current should be -1 when user calls this method.
public static int largestElement(int[] array) {
if (array.length > 0) {
boolean resetCurrent = false;
if (current == -1) {
// Initialization
current = 0;
resetCurrent = true;
} else if (current >= array.length - 1) {
// Base case
return array[array.length - 1];
}
try {
int i = current++;
return Math.max(array[i], largestElement(array));
} finally {
if (resetCurrent) {
current = -1;
}
}
}
throw new IllegalArgumentException("Input array is empty.");
}
If you can create another method, everything would be much simpler.
private static int recursiveFindLargest(int [] array, int i) {
if (i > 0) {
return Math.max(array[i], recursiveFindLargest(array, i-1));
} else {
return array[0];
}
}
public static int largestElement(int [] array) {
// For empty array, we cannot return a value to indicate this situation,
//all integer values are possible for non-empty arrays.
if (array.length == 0) throw new IllegalArgumentException();
return recursiveFindLargest(array, array.length - 1);
}
For this problem you really need to think about working with the base case. Take a look at some of the simple cases you would have to deal with:
If the array is length 1, then you return the only value
If the array is length 2, then you return the maximum of the two values
If the array is length 3, then ?
From the above we can get an idea of the structure of the problem:
if array.length == 1 then
return array[0]
else
return the maximum of the values
In the above if we have only one element, it is the maximum value in the list. If we have two values, then we have to find the maximum of those values. From this, we can then use the idea that if we have three values, we can find the maximum of two of them, then compare the maximum with the third value. Expanding this into pseudo code, we can get something like:
if array.length == 1 then
return array[0]
else
new array = array without the first element (e.g. {1, 2, 3} => {2, 3})
return maximum(array[0], largestElement(new array))
To explain the above a little better, think of execution like a chain (example for {1, 2, 3}).
Array: {1, 2, 3}, maximum(array[0] = 1, largestElement(new array = {2, 3}))
Array: {2, 3}, maximum(array[0] = 2, largestElement(new array = {3}))
Array: {3}, array[0] = 3 => length is 1 so return 3
The above then rolls back up the 'tree' structure where we get:
maximum (1, maximum(2, (return 3)))
Once you have the maximum value, you can use the sample principle as above to find the index with a separate method:
indexOf(array, maximum)
if array[0] == maximum then
return 0
else if array.length == 1 then
return -1
else
new array = array without the first element (e.g. {1, 2, 3} => {2, 3})
result = indexOf(new array, maximum)
return (result == -1) ? result : result + 1
For looking into this more, I would read this from the Racket language. In essence it shows the idea of array made purely from pairs and how you can use recursion to do iteration on it.
If you are interested, Racket is a pretty good resource for understanding recursion. You can check out University of Waterloo tutorial on Racket. It can give you a brief introduction to recursion in an easy to understand way, as well as walking you through some examples to understand it better.
You don't need to keep a largest variable outside your method - that's generally not a good practice with recursion which should return all context of the results.
When you think about recursion try to think in terms of a simple base case where the answer is obvious and then, for all other cases how to break it down into a simpler case.
So in pseduo-code your algorithm should be something like:
func largest(int[] array)
if array has 1 element
return that element
else
return the larger of the first element and the result of calling largest(remaining elements)
You could use Math.max for the 'larger' calculation.
It's unfortunate that you can't change the arguments as it would be easier if you could pass the index to start at or use lists and sublists. But your copying method should work fine (assuming efficiency isn't a concern).
An alternative to the algorithm above is to make an empty array the base case. This has the advantage of coping with empty arrays (by return Integer.MIN_VALUE):
int largest(int[] array) {
return array.length == 0
? Integer.MIN_VALUE
: Math.max(array[0], largest(Arrays.copyOfRange(array, 1, array.length)));
}
Here is working example of code with one method param
public int max(int[] list) {
if (list.length == 2) return Math.max(list[0], list[1]);
int max = max(Arrays.copyOfRange(list, 1, list.length));
return list[0] < max ? max : list[0];
}
private static int maxNumber(int[] arr,int n,int max){
if(n<0){
return max;
}
max = Math.max(arr[n],max);
return maxNumber(arr,n-1,max);
}

Looping data structure in Java

Is there an Iterator to loop over data structure in cycles?
Let's say there is an array:
int[] arr = {-1,5,7,-1,-1,-1}
I want to find index of first non -1 value from this array and starting to search from the random position (idx = random.nextInt(arr.length)). For example idx = 4;
So first check if arr[4] == -1, then if arr[5] == -1 and so on. If the end of the array reached then start from 0 position and continue until non -1 found. It is guaranteed that there will be at least one value not equal to -1 in the array.
This can be done so:
int idx = -1;
for (int i = random.nextInt(arr.length); ; i++) {
if (i == arr.length) {
/** start over */
i = 0;
}
if (-1 != arr[i]) {
idx = i;
break;
}
}
Or so:
int idx = -1;
int i = random.nextInt(arr.length);
do {
if (-1 != arr[i]) {
idx = i;
}
i == arr.length ? i=0 : i++;
} while (-1 == idx);
Is there an Iterator, that supports cycling (call next() , if the end of array reached then automatically start from 0)?
Limitations: 1) efficiency is not considered; 2) standard Java API is preferred.
in java API there is no such api which satisfy your problem but you can made it by your own.
what you can do is use List to create LinkedList. to solve your problem.
you can extend List to your class (CircularLinkedList extends List) & then override method hasNext() & getNext() thats all you need.
I don't think there are any iterators that let you know the index of the element as you call next(), so you'd have to keep track of the current index separately. You might be able to build up a "wrap-around" iterator using Guava's Iterators.concat (or some other third-party class) to concatenate an iterator over the trailing part of the array with an iterator over the leading part. However, I think the code is likely to be more complex than a simple for loop or two.
I believe there is no such circular Iterator that will automatically go to the beginning of the array once the end has been reached. I have created one below (not tested, and design is flawed), which requires an entirely new class of code, and is much longer than your short for/while loops.
public class MyCircularIterator<E> implements Iterator<E> {
private List<E> list;
private int pos;
public MyCircularIterator(List<E> list) {
this(list, 0);
}
public MyCircularIterator(List<E> list, int start) {
this.list = list;
pos = start;
}
public boolean hasNext() {
if(list.get(pos) != -1) return false;
return true;
}
public E next() {
if(hasNext()) {
E obj = list.get(pos);
pos = (pos + 1) % list.size();
return obj;
}
}
public void remove() {
list.remove(this.nextIndex);
}
}

Inserting objects into arraylist

I have an arraylist of 50 RANDOM integers. I ask a user to remove a number and all occurences of that number are removed from the list. I did that using
while (randInts.contains(removeInt) )
{
if (randInts.get(i) == removeInt)
randInts.remove(randInts.get(i));
i++;
}
System.out.println("\n" + randInts.toString());
System.out.println("\n" + randInts.size());`
The other part of the problem is to prompt the user to enter another number. The removed number from above is inserted after each occurrence of the second prompted number. I am having issues with the second part as I keep getting IndexOutOfBoundsException.
Use a LinkedList instead; it's a much better choice when you need in-order traversal but not really random access, and when you need to insert and remove elements in the middle of the list.
You can accomplish what you're wanting (removing all instances of removeInt and inserting removeInt after every instance of insertAfterInt) with a simple traversal of the list's iterator:
ListIterator<Integer> li = randInts.listIterator();
while(li.hasNext()) {
int i = li.next();
if(removeInt == i) // assumes removeInt is an int; use equals() for Integer
li.remove();
if(insertAfterInt == i)
li.add(removeInt); // the iterator will skip this element, so it won't get removed
}
I see two big issues: You're not bounding i to anything, and you wrote an n^2 loop (you can do this in linear time).
You're shrinking the size of the `List` as you go...take this simple example:
Say you want to remove all instances of 5
Given a list that looks like {1,2,3,5,5}
When i = 3 you will remove the first 5, making the list look like: {1,2,3,5}
then you will attempt to remove the element at i = 4, but that element you want to remove is really now at i = 3, and you'll get the IndexOutOfBoundsException
You don't want to use a `contains`, as this expands the worst case performance of your loop to n^2, this would be faster:
int size = randInts.size() - 1;
for (int i = size; i >= 0; i--){
if (randInts.get(i).equals(removeInt))
randInts.remove(i);
}
while (randInts.contains(removeInt) )
{
if(i<randInts.size());
{
if (randInts.get(i) == removeInt)
randInts.remove(randInts.get(i));
}//if
i++;
}while
I am guessing you are starting with a collection of 50 items (randInts) and removing the items that users enter (i)?
If that is the case, once your remove an item, your collection then only 49 indexes left and get gets by the index. Try something like...
if (randInts.contains(i)){
randInts.remove(randInts.indexOf(i));
}
This is n^2, but it should work
int i = 0;
while(i < loFnumbers.size()){
if(loFnumbers.get(i) == removeInt){
loFnumbers.remove(i);
continue;
}
i++;
}
Here's an approach that avoids any state mutation (i.e. randInts is never modified):
package so;
import java.util.ArrayList;
public class SO_18836900 {
public static void main(String[] args) {
// build a collection of random ints
ArrayList<Integer> randInts = new ArrayList();
for (int i = 0; i < 50; i ++) {
randInts.add((int)(Math.random() * 5));
}
// create a collection with all 3s filtered out
ArrayList<Integer> filtered = filterOut(randInts, 3);
System.out.println(filtered);
System.out.println(filtered.size());
// create a collection with a 99 inserted after each 4
ArrayList<Integer> insertedAfter = insertAfter(randInts, 4, 99);
System.out.println(insertedAfter);
System.out.println(insertedAfter.size());
}
static ArrayList<Integer> filterOut(Iterable<Integer> xs, int toRemove) {
ArrayList<Integer> filteredInts = new ArrayList();
for (int x : xs) {
if (x != toRemove) filteredInts.add(x);
}
return filteredInts;
}
static ArrayList<Integer> insertAfter(Iterable<Integer> xs, int trigger, int toInsert) {
ArrayList<Integer> insertedAfter = new ArrayList();
for (int x : xs) {
insertedAfter.add(x);
if (x == trigger) insertedAfter.add(toInsert);
}
return insertedAfter;
}
}
if (randInts.get(i) == removeInt)
randInts.remove(randInts.get(i));
i++;
You're never checking stopping conditions. Fix is:
while (randInts.contains(removeInt) )
{
i=0;
while(i<randInts.size()){
if (randInts.get(i) == removeInt)
randInts.remove(randInts.get(i));
i++;
}
}
Dont use == on "Integers" you are comparing references.
Either unbox into int or use equals(

Java: removing elements from a collection

I have a collection, and I want to implement the add() method, such that only positive integers can be added to the collection. The collection can hold 4 values, and I have used the code below to initialize every value as "-1".
public class Bag implements Collection {
private int[] elements;
public Bag() {
elements = new int[Runner.SIZE_OF_COLLECTION];
for (int i = 0; i < Runner.SIZE_OF_COLLECTION; i++) {
elements[i] = -1;
}
}
So far in the method add() below, I have this loop iterating through each element in the collection, and replacing each element that's less than 0 with the positive integer that I want to add ("toAdd").
The problem is, I only want to add the positive integer "toAdd" once, and without a break in the loop, the method replaces EVERY element "-1" in the collection with the positive integer. With the break in the loop, the method fails to add the positive integer at all. Any ideas on how I can get the method to add the positive integer to the collection only once?
public void add(int toAdd) {
for (int i = 0; i < Runner.SIZE_OF_COLLECTION; i++) {
if (elements[i] <= 0 && toAdd>0) {
elements[i] = toAdd;
}
break;
}
}
Thanks in advance!
Move the break into the if statement.
You could use an ArrayList instead of an int array. With an ArrayList, you could get the index of the first occurence of -1 and use the set method to add your new value at that index.
This replaces the first value from elements, which is equal or less than 0, with value from toAdd argument.
public void add(int toAdd) {
for (int i = 0; i < Runner.SIZE_OF_COLLECTION; i++) {
if (elements[i] <= 0 && toAdd>0) {
elements[i] = toAdd;
break;
}
}
}
The add method for the interface Collection takes an Object (or a generic type, which you have not specified). If you are trying to override / implement the collection interface method with your add method, then the method signature is incorrect, and it will never be called.
Your class needs to look like:
public class Bag implement Collection<Integer>
{
// ... other necessary methods
public boolean add(Integer i)
{
// your method...
}
}
And probably easier than your implementation would be to do:
public class Bag extends java.util.ArrayList<Integer>
{
#Override
public boolean add(Integer i)
{
if ((i != null) && (i > 0)) super.add(e);
}
}
You probably need to override the other add methods as well, although truthfully, it would be better to encapsulate the ArrayList instead of extending it.

How do you remove the first instance of an element value in an array?

Add a method void removeFirst(int newVal) to the IntegerList class that removes the first occurrence of a value from the list. If the value does not appear in the list, it should do nothing (but it's not an error). Removing an item should not change the size of the array, but note that the array values do need to remain contiguous, so when you remove a value you will have to shift everything after it down to fill up its space. Also remember to decrement the variable that keeps track of the number of elements.
Please help, I have tried all of the other solutions listed on this site regarding "removing an element from an array" and none have worked.
This method supports the same functionality as Collection.remove() which is how an ArrayList removes the first matching element.
public boolean remove(int n) {
for (int i = 0; i < size; i++) {
if (array[i] != n) continue;
size--;
System.arraycopy(array, i + 1, array, i, size - i);
return true;
}
return false;
}
Rather than write this code yourself, I suggest you look at Trove4J's TIntArrayList which is a wrapper for int[] You can also read the code for ArrayList to see how it is written.
You could do this:
int count; //No of elements in the array
for(i=0;i<count;i++)
{
if(Array[i]==element )
{
swap(Array,i,count);
if(count)
--count;
break;
}
}
int swap(int Array[],int i,int count)
{
int j;
for(j=i;j<=count-i;j++)
a[i]=a[i+1];
}
This is not the Full Implementation.You have to create a class and do this.
Using the method below
public static <TypeOfObject> TypeOfObject[] removeFirst(TypeOfObject[] array, TypeOfObject valueToRemove) {
TypeOfObject[] result = Arrays.copyOf(array, array.length - 1);
List<TypeOfObject> tempList = new ArrayList<>();
tempList.addAll(Arrays.asList(array));
tempList.remove(valueToRemove);
return tempList.toArray(result);
}
You can remove the first element of any array by calling the method as demonstrated in the below JUnit test.
#Test
public void removeFirstTest() {
// Given
Integer valToRemove = 5;
Integer[] input = {1,2,3,valToRemove,4,valToRemove,6,7,8,9};
Integer[] expected = {1,2,3,4,valToRemove,6,7,8,9};
// When
Integer[] actual = removeFirst(input, valToRemove);
// Then
Assert.assertArrayEquals(expected, actual);
}

Categories

Resources