Write a method deleteElement which takes as input an int[] and an int target and deletes all occurrences of target from the array. The method should return the newint[]
. Question to consider:
Why is it that we have to return an array and can't simply change the input parameter array?
public class warm5{
public static void main(String[] args){
int[] array1= {1,2,2,3,4,5,2};
int target1 = 2;
deleteElement(array1,target1);
public static int[] deleteElement(int[] array, int target){
for(int i = 0, i<array.length, i++){
if(array1[i] == target){
}
}
}
}
}
Here is what i wrote, im not sure how to continue it to remove the 2's in the array.
please help!
You can't delete elements from an array, by definition they're of fixed size. What you can do is create a new array, copy all the elements from the old array except the ones that you intend to delete and return the new array. Or, use an ArrayList, which has operations that allow removing elements:
public E remove(int index)
public boolean remove(Object o)
public boolean removeAll(Collection<?> c)
protected void removeRange(int fromIndex, int toIndex)
First, iterate through your array and figure out how many of your target element are present.
Once you know that, you know the size of your new array. As Oscar mentions, you can't "remove" from an array, you just make a new array without the elements you don't want in it.
int targetCount = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] == target) {
targetCount++;
}
}
Now you know how many items will be in your new array: array.length-targetCount.
int[] newArray = new int[array.length-targetCount];
int newArrayIdx = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] != target) {
newArray[newArrayIdx] = target;
newArrayIdx++;
}
}
Here we iterate through the old array and check each element to see if it's our target. If it's not, we add it to the new array. We have to keep track of our old array's index and our new array's index independently or we may risk trying to assign an index outside of the array bounds.
This is a common interview question. In the solution presented by Oscar you do not know what will be the size of the new array. So the solution does not work or is memory inefficient.
Trick is to loop over the array and at any time when you encounter an element equal to the given element you put that element towards the end of the array and swap it with the element that was there at the end position. By doing this you are collecting all occurrences of given element at the end of the array.
Here is a working logic
deleteElement(int[] given, int elem) {
int endIdx = array.length - 1;
for(int idx = 0; idx <= endIdx; idx++) {
if(given[idx] == elem) {
//swap idx with endIdx
int tmp = given[endIdx];
given[endIdx] = given[idx];
given[idx] = tmp;
endIdx--;
}
}
return Arrays.copyOfRange(given, 0, endIdx);
}
Related
I have a problem with one of our old exam tasks.
the task is
"the method positions should return a field containing exactly the positions of those elements of the list that have null as content. if there are no such elements than return a field with the length 0"
the code starts with :
public int[] positions() {
int[] result = new int[0];
I keep getting stuck on because of the "new int[0]" when I tried solving the problem without it I managed to get somewhat of a result. but I don't know how to do it with this part.
Just think for a moment what the code is doing here.
int[] result = new int[0];
creates an empty, fixed lenght, primitive array. This array cannot be further expanded.
Your exam task would be translated as (simplifying at a large degree):
public int[] positions(final Object[] objects) {
// Initialize the array with the max possible size, which is the input array size
final int[] positions = new int[objects.lenght];
int j = 0;
for (int i = 0; i < objects.length; i++) {
if (objects[i] == null) {
// Assign the index of the null value to the holder array.
// Increment j, which is the index of the first free position in the holder array
positions[j++] = i;
}
}
// This will return a copy of the "positions" array, truncated at size j
return Array.copyOf(positions, j);
}
I found this code online and it works well to permute through the given array and return all possible combinations of the numbers given. Does anyone know how to change this code to incorporate a 2D array instead?
public static ArrayList<ArrayList<Integer>> permute(int[] numbers) {
ArrayList<ArrayList<Integer>> permutations = new ArrayList<ArrayList<Integer>>();
permutations.add(new ArrayList<Integer>());
for ( int i = 0; i < numbers.length; i++ ) {
ArrayList<ArrayList<Integer>> current = new ArrayList<ArrayList<Integer>>();
for ( ArrayList<Integer> p : permutations ) {
for ( int j = 0, n = p.size() + 1; j < n; j++ ) {
ArrayList<Integer> temp = new ArrayList<Integer>(p);
temp.add(j, numbers[i]);
current.add(temp);
}
}
permutations = new ArrayList<ArrayList<Integer>>(current);
}
return permutations;
}
This is what I have attempted:
public static int[][] permute(int[] numbers){
int[][] permutations = new int[24][4];
permutations[0] = new int[4];
for ( int i = 0; i < numbers.length; i++ ) {
int[][] current = new int[24][4];
for ( int[] permutation : permutations ) {
for ( int j = 0; j < permutation.length; j++ ) {
permutation[j] = numbers[i];
int[] temp = new int[4];
current[i] = temp;
}
}
permutations = current;
}
return permutations;
}
However this returns all zeroes. I chose 24 and 4 because that is the size of the 2D array that I need.
Thanks
It’s not really that easy. The original code exploits the more dynamic behaviour of ArrayList, so a bit of hand coding will be necessary. There are many correct thoughts in your code. I tried to write an explanation of the issues I saw, but it became too long, so I decided to modify your code instead.
The original temp.add(j, numbers[i]); is the hardest part to do with arrays since it invloves pushing the elements to the right of position j one position to the right. In my version I create a temp array just once in the middle loop and shuffle one element at a time in the innermost loop.
public static int[][] permute(int[] numbers) {
// Follow the original here and create an array of just 1 array of length 0
int[][] permutations = new int[1][0];
for (int i = 0; i < numbers.length; i++) {
// insert numbers[i] into each possible position in each array already in permutations.
// create array with enough room: when before we had permutations.length arrays, we will now need:
int[][] current = new int[(permutations[0].length + 1) * permutations.length][];
int count = 0; // number of new permutations in current
for (int[] permutation : permutations) {
// insert numbers[i] into each of the permutation.length + 1 possible positions of permutation.
// to avoid too much shuffling, create a temp array
// and use it for all new permutations made from permutation.
int[] temp = Arrays.copyOf(permutation, permutation.length + 1);
for (int j = permutation.length; j > 0; j--) {
temp[j] = numbers[i];
// remember to make a copy of the temp array
current[count] = temp.clone();
count++;
// move element to make room for numbers[i] at next position to the left
temp[j] = temp[j - 1];
}
temp[0] = numbers[i];
current[count] = temp.clone();
count++;
}
assert count == current.length : "" + count + " != " + current.length;
permutations = current;
}
return permutations;
}
My trick with the temp array means I don’t get the permutations in the same order as in the origianl code. If this is a requirement, you may copy permutation into temp starting at index 1 and shuffle the opposite way in the loop. System.arraycopy() may do the initial copying.
The problem here is that you really need to implement properly the array version of the ArrayList.add(int,value) command. Which is to say you do an System.arraycopy() and push all the values after j, down one and then insert the value at j. You currently set the value. But, that overwrites the value of permutation[j], which should actually have been moved to permutations[j+1] already.
So where you do:
permutation[j] = numbers[i];
It should be:
System.arraycopy(permutation,j, permutations, j+1, permutations.length -j);
permutation[j] = numbers[i];
As the ArrayList.add(int,value) does that. You basically wrongly implemented it as .set().
Though personally I would scrap the code and go with something to dynamically make those values on the fly. A few more values and you're talking something prohibitive with regard to memory. It isn't hard to find the nth index of a permutation. Even without allocating any memory at all. (though you need a copy of the array if you're going to fiddle with such things without incurring oddities).
public static int[] permute(int[] values, long index) {
int[] returnvalues = Arrays.copyOf(values,values.length);
if (permutation(returnvalues, index)) return returnvalues;
else return null;
}
public static boolean permutation(int[] values, long index) {
return permutation(values, values.length, index);
}
private static boolean permutation(int[] values, int n, long index) {
if ((index == 0) || (n == 0)) return (index == 0);
int v = n-(int)(index % n);
int temp = values[n];
values[n] = values[v];
values[v] = temp;
return permutation(values,n-1,index/n);
}
Let's say I have an array in the length of n, and the only values that can appear in it are 0-9. I want to create a recursive function that returns the number of different values in the array.
For example, for the following array: int[] arr = {0,1,1,2,1,0,1} --> the function will return 3 because the only values appearing in this array are 0, 1 and 2.
The function receives an int array and returns int
something like this:
int numOfValues(int[] arr)
If you are using Java 8, you can do this with a simple one-liner:
private static int numOfValues(int[] arr) {
return (int) Arrays.stream(arr).distinct().count();
}
Arrays.stream(array) returns an IntStream consisting of the elements of the array. Then, distinct() returns an IntStream containing only the distinct elements of this stream. Finally, count() returns the number of elements in this stream.
Note that count() returns a long so we need to cast it to an int in your case.
If you really want a recursive solution, you may consider the following algorithm:
If the input array is of length 1 then the element is distinct so the answer is 1.
Otherwise, let's drop the first element and calculate the number of distinct elements on this new array (by a recursive call). Then, if the first element is contained in this new array, we do not count it again, otherwise we do and we add 1.
This should give you enough insight to implement this in code.
Try like this:
public int myFunc(int[] array) {
Set<Integer> set = new HashSet<Integer>(array.length);
for (int i : array) {
set.add(i);
}
return set.size();
}
i.e, add the elements of array inside Set and then you can return the size of Set.
public int f(int[] array) {
int[] counts = new int[10];
int distinct = 0;
for(int i = 0; i< array.length; i++) counts[array[i]]++;
for(int i = 0; i< counts.length; i++) if(counts[array[i]]!=0) distinct++;
return distinct;
}
You can even change the code to get the occurrences of each value.
You can try following code snippet,
Integer[] arr = {0,1,1,2,1,0,1};
Set<Integer> s = new HashSet<Integer>(Arrays.asList(arr));
Output: [0, 1, 2]
As you asked for a recursive implementation, this is one bad way to do that. I say bad because recursion is not the best way to solve this problem. There are other easier way. You usually use recursion when you want to evaluate the next item based on the previously generated items from that function. Like Fibonacci series.
Ofcourse you will have to clone the array before you use this function otherwise your original array would be changed (call it using countDistinct(arr.clone(), 0);)
public static int countDistinct(int[] arr, final int index) {
boolean contains = false;
if (arr == null || index == arr.length) {
return 0;
} else if (arr.length == 1) {
return 1;
} else if (arr[index] != -1) {
contains = true;
for (int i = index + 1; i < arr.length; i++) {
if (arr[index] == arr[i]) {
arr[i] = -1;
}
}
}
return countDistinct(arr, index + 1) + (contains ? 1 : 0);
}
int numOfValues(int[] arr) {
boolean[] c = new boolean[10];
int count = 0;
for(int i =0; i < arr.length; i++) {
if(!c[arr[i]]) {
c[arr[i]] = true;
count++;
}
}
return count;
}
This question already has answers here:
How to add an element at the end of an array?
(6 answers)
Closed 6 years ago.
Hello i need to manually implement an arraylist.add() method using nothing but arrays and an array copy method but im having trouble doing it . The specification of the method is that the method inserts an element at a specified position and shifts any of the elements currently in the position to the right and add one to the indices expanding the size of the array by one so all elements fit . Someone please help .
private Object [] list;
final int maxObjects = 100;
public ListOfObjects()
{
list= new Object[maxObjects];
}
public ListOfObjects(Object[]o)
{
list= o;
}
public void add(Object element,int index)
{
Object[] newData = new Object[list.length+1];
for(int i =0; i < index; i++)
{
newData[i] = list[i];
newData[list] = element;
}
for(int i = index; i < list.length; i++)
{
newData[i+1] = list[i];
}
}
Adding an element to an index of an Object array,
Object[] myObjects;
public static void addObject(Object obj, int index) {
// Assuming you want something in your empty array
if(myObjects == null) {
myObjects = new Object[] { obj };
return;
}
ArrayList<Object> temp = new ArrayList<Object>();
for(int i = 0; i < myObjects.length; i++) {
if(i == index)
temp.add(obj);
temp.add(myObjects[i]);
}
myObjects = temp.toArray(new Object[temp.size()]);
}
The javadoc of System.arrayCopy speaks specifically to the case of the src and dest being the same array:
If the src and dest arguments refer to the same array object, then the
copying is performed as if the components at positions srcPos through
srcPos+length-1 were first copied to a temporary array with length
components and then the contents of the temporary array were copied
into positions destPos through destPos+length-1 of the destination
array.
If your backing list is of sufficient size, then you simply need to use arrayCopy to move the affected indexes over 1.
//shift everything after the index over
System.arrayCopy(list, index, list, index + 1, list.length - index);
//place new value in index
list[index] = element;
Otherwise you need to create a new array, then use arrayCopy to copy everything before the inserting index.
Object[] newList = new Object[calcSize()];
//first copy everything before index if index is not 0
if (index > 0)
{
System.arrayCopy(list, 0, newList, 0, index);
}
newList[index] = element;
System.arrayCopy(list, index, newList, index+1, list.length - index);
You logic looks wrong to me. You should do something like -
Object[] newData = new Object[list.length+1];
for(int i =0; i < index; i++)
{
newData[i] = list[i];
}
newData[index] = element;
for(int i = index; i < list.length; i++)
{
newData[i+1] = list[i];
}
This solution takes advantage of the ArrayList iterator, which returns objects in the proper sequence:
ArrayList<Object> elementInserter(ArrayList<Object> inArray, Object element, int index){
ArrayList<Object> outArray = new ArrayList<Object>(inArray.size() + 1);
outArray.addAll(inArray.subList(0, index));
outArray.add(element);
outArray.addAll(inArray.subList(index, inArray.size()));
return outArray;
}
Here's what the layout is
index num
0 [10]
1 [20]
2 [30]
(Add 35 here)
3 [40] Move elements down
4 [50]
5 [60]
6 [70]
then my method is this
public static void method(int[] num, int index, int addnum)
{
}
How can i add 35 in there?
Tried this:
public static void method(int[] num, int index, int addnum)
{
int index = 10;
for(int k = num.length k>3; k++)
{
Num[k]=num[k++]
}
Num[3] = 35;
As this is something you should accomplish yourself, I will only provide the method to implement it, not the code:
If you would set the number at position index, you would overwrite the value that was there previously. So what you need to do is move every element one position towards the end of the array starting from index: num[x] becomes num[x+1], etc.
You will find out that you need to do this in reverse order, otherwise you will fill your array with the value in num[index].
During this process you will need to decide what to do with the last entry of the array (num[num.length - 1]):
You could just overwrite it, discarding the value
You could return it from your function
You could throw an exception if it is non-zero
You could create a new array that is 1 entry larger than the current array instead to keep all values
etc.
After this, you have duplicated num[index]: the value is present in num[index+1], too, as you have moved it away.
Now it is possible to write the new value at the desired position without overriding an existing value.
EDIT
You have several errors in your code:
You increment k, you need to decrement it (k--, not k++)
You modify k again in your loop body: it is updated twice in each cycle
If you start with k = num.length, you will try to write at num[num.length + 1], which is not possible
Very crudely, you want to do something like this:
public static void(int[] num, int index, int addnum)
{
// initialize new array with size of current array plus room for new element
int[] newArray = new int[num.length + 1];
// loop until we reach point of insertion of new element
// copy the value from the same position in old array over to
// same position in new array
for(int i = 0; i < index; i++)
{
newArray[i] = num[i];
}
i = i + 1; // move to position to insert new value
newArray[i] = addnum; // insert the value
// loop until you reach the length of the old array
while(i < num.length)
{
newArray[i] = num[i-1];
}
// finally copy last value over
newArray[i + 1] = num[i];
}
You need to
allocate a new array with room for one new element.
int[] newArray = new int[oldArray.length + 1];
Copy over all elements and leave room for the one to insert.
for (int i = 0; i < newArray.length - 1; i++)
newArray[i < insertIndex ? i : i + 1] = oldArray[i];
Insert 35 in the empty spot.
newArray[insertIndex] = numberToInsert;
Note that it's not possible to do in a method like this:
public static void method(int[] num, int index, int addnum)
^^^^
since you can't change the length of num.
You need to allocate a new array, which means that need to return the new array:
public static int[] method(int[] num, int index, int addnum)
^^^^^
and then call the method like this:
myArr = method(myArr, 3, 35);
Since this very closely resembles homework what you need to realize is that you cannot dynamically increase the size of an array. So in your function:
public static void(int[] num, int index, int addnum)
{
int[] temp = new int[num.length *2];
for(int i = 0; i < index; i++)
copy num[i] into temp[i]
insert addnum into temp[index]
fill temp with remaining num values
}
That pseudocode above should get you started.
What you're looking for is an insertion sort.
It's classwork, so it's up to you to figure out the proper code.
Well, you can't unless there is "extra space" in your array, and then you can shift all elements [starting from index] one element to the right, and add 35 [num] to the relevant place.
[what actually happen is that the last element is discarded out].
However - a better solution will probably be to use an ArrayList, and use the method myArrayList.add(index,element)
How about this?
public class test {
public static void main(String[] arg) throws IOException
{
int[] myarray={1,2,3,5,6};//4 is missing we are going to add 4
int[] temp_myarray=myarray;//take a temp array
myarray=addElement(myarray,0);//increase length of myarray and add any value(I take 0) to the end
for(int i=0;i<myarray.length;i++)
{ if(i==3) //becaues I want to add the value 4 in 4th place
myarray[i]=4;
else if(i>3)
myarray[i]=temp_myarray[i-1];
else
myarray[i]=temp_myarray[i];
}
for(int i=0;i<myarray.length;i++)
System.out.print(myarray[i]);//Print new array
}
static int[] addElement(int[] arr, int elem) {
arr = Arrays.copyOf(arr, arr.length + 1);
arr[arr.length - 1] = elem;
return arr;
}
}