Nested loop extracting index values into new array - java

I am trying to extract specific index values from an array, and place them into a new array. The primary array values are as follows:
int a[] = {7, 8, 9, 9, 8, 7};
The call I am making to the method is as follows:
print(findAll (a,7));
print(findAll (a,2));
The method I am using is as follows:
public int[] findAll(int a[], int target)
{
int count = 0;
int i = 0;
int index = 0;
int spotIndex = 0;
for (i = 0; i < a.length; i++)
{
if (a[i] == target)
count = count + 1;
spotIndex = i;
}
int result[] = new int[count];
for (index = 0; index < count; index++)
{
result[index] = spotIndex;
index++;
}
return result;
}
The results should be:
{0, 5}
{}
My results are below; if I change the target argument I get the same results.
{5, 0}
{}
Thanks in advance....

Small advice:
for (index = 0; index < count; index++)
{
result[index] = spotIndex;
index++;
}
you index++ call double times. This is bad practice to use index in method scope, better is:
for (int index = 0; index < count; index++)
{
result[index] = spotIndex;
}
Notice that you put spotIndex (the same value) in all result elements.
Why you don't use List?
public Integer[] findAll(int a[], int target) {
List<Integer> result = new ArrayList<Integer>();
for (int i=0; i<a.length; i++) {
if (a[i] == target) {
result.add(i);
}
}
return result.toArray(new Integer[result.size()]);
}

spotIndex isn't serving the purpose you thought needed for.
for (i = 0; i < a.length; i++)
{
if (a[i] == target)
count = count + 1;
spotIndex = i; // spotIndex comes in for loop but not in if condition.
// and this gets modified at every step in loop.
// simply assigning value of i to it.
}
Instead the logic should be -
for (i = 0; i < a.length; i++)
{
if (a[i] == target)
count = count + 1;
}
count gives the number of times target is repeated. Now, create an array of size count to actually copy those element's index in to the array.
int result[] = new int[count];
int copyIndex = 0;
for (index = 0; index < a.length; index++)
{
if( a[index] == target )
{
result[copyIndex] = index ;
++copyIndex;
if( copyIndex == count )
return result ;
}
}
I don't see the use of this statement - spotIndex = i; in first loop.
Note: The logic assumes that search element( i.e., target ) is definitely present in the array. With slight modification though, we can return the indexes if element is present only.

Related

How can I count subsequently equal values in an int array

I would like to count subsequently equal values in an int array and return an array with the count and another array with the value order.
E.g. i would like to transform:
int arr = {0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,2,2,2,2,0,0,0,1,1,1,2,2,2,2,0,0,0,0};
To:
int arr = {11,5,4,3,3,4,4}; // The count
int idx = {0,1,2,0,1,2,0}; // The order
Can you help me achieve this?
This should do the job:
int[] arr = {0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,2,2,2,2,0,0,0,1,1,1,2,2,2,2,0,0,0,0};
//First determine how many subsequently equal values there are
int countEquals = 1;
for (int i = 1; i < arr.length; i++) {
if (arr[i] != arr[i-1]) {
countEquals++;
}
}
//Then calculate the order and count
int[] count = new int[countEquals];
int[] order = new int[countEquals];
int index = 0;
Arrays.fill(count, 1);
for (int i = 1; i < arr.length; i++) {
if (arr[i] == arr[i-1]) {
count[index]++;
} else {
order[index] = arr[i-1];
index++;
}
}

How to make a new array out of only even numbers?

Basically, I am trying to make an entirely new array of a new length that contains only the even ints in an array of integers.
However, I am getting an index out of bounds error. Can you help me find what I did wrong?
import java.util.Arrays;
public class findevens {
public static void main(String[] args) {
System.out.println(Arrays.toString(evens(new int[]{4,8,19,3,5,6})));
}
public static int[] evens(int[] arr) {
//create new array by determining length
//of even number ints
int length = 0;
int j = 0;
for (int i = 0; i < arr.length; i++)
{
if (arr[i] % 2 == 0) {
length++;
}
}
int[] result = new int[length];
//add even ints to new array
for (int i = 0; i < arr.length; i++)
{
if (arr[i] % 2 == 0) {
result[i] += arr[i];
}
}
return result;
}
}
You should use a new variable to keep track of the current result index (let's say, j):
public static int[] evens(int[] arr) {
int length = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 == 0) {
length++;
}
}
int[] result = new int[length];
int j = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 == 0) {
// Access result with `j` and update its value
result[j++] = arr[i];
}
}
return result;
}
Also, you can you streams:
int[] array = {1, 3, 4, 5, 6};
int[] even = IntStream.of(array).filter(item -> item%2 == 0).toArray();
System.out.println(Arrays.toString(even));
You need a new index variable for the result array and your assignment is also wrong as instead of assigning you are adding the even number to the result array element.
int j = 0;
int[] result = new int[length];
// add even ints to new array
for (int i = 0; i < arr.length; i++)
{
if (arr[i] % 2 == 0)
{
result[j++] = arr[i];
}
}
Problem is you are using i for the result array AND the original array. You should only increment the result array inside of the IF (when you find an even number) otherwise, you go out of bounds due to i (the original arr) being a larger size than the result array.
public static int[] evens(int[] arr) {
//create new array by determining length
//of even number ints
int length = 0;
int j = 0;
for (int i = 0; i < arr.length; i++)
{
if (arr[i] % 2 == 0) {
length++;
}
}
int[] result = new int[length];
//add even ints to new array
int resultCount = 0;
for (int i = 0; i < arr.length; i++)
{
if (arr[i] % 2 == 0) {
result[resultCount] += arr[i];
resultCount++;
}
}
return result;
}
Simply when you want to assign a value to result[] you do it with the index in the array arr, 0, 1 and 5. You just have to declare an auxiliary int aux = 0; variable before second loop and increment according to arr[i] % 2 == 0 so true
result[i] += arr[i];
a
int aux = 0;
result[aux++] += arr[i];
Complete code
public class findevens {
public static void main(String[] args) {
System.out.println(Arrays.toString(evens(new int[]{4,8,19,3,5,6})));
}
public static int[] evens(int[] arr) {
//create new array by determining length
//of even number ints
int length = 0;
int j = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 == 0) {
length++;
}
}
int[] result = new int[length];
int aux = 0;
//add even ints to new array
for (int i = 0; i < arr.length; i++){
if (arr[i] % 2 == 0) {
result[aux++] += arr[i];
}
}
return result;
}
}
Since you don't really know how long the resultant array will be you can copy them to the front of the current array. Then use the final location as the count of values.
int[] input = {1,2,3,4,5,6,7,8,9};
int k = 0;
for(int i = 0; i < input.length; i++) {
if (input[i] % 2 == 0) {
input[k++] = input[i];
}
}
int[] evens = Arrays.copyOf(input, k);
System.out.println(Arrays.toString(evens));
Prints
[2, 4, 6, 8]
A simple way is to filter even numbers using the Stream API and return the result as an array.
Arrays.stream(arr)
.filter(n -> n % 2 == 0)
.toArray();
Demo:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
System.out.println(Arrays.toString(evens(new int[] { 4, 8, 19, 3, 5, 6 })));
}
static int[] evens(int[] arr) {
return Arrays.stream(arr).filter(n -> n % 2 == 0).toArray();
}
}
Output:
[4, 8, 6]
What went wrong with your code:
result.length is 3 and therefore in result[], the maximum index you can access is 2 (i.e. result.length -1) whereas your second loop counter goes up to 5 (i.e. arr.length - 1) and you are using the same counter to access elements in result[] resulting in ArrayIndexOutOfBoundsException.
If you want to do it in your own way, you need to use a separate counter for result[] e.g.
int[] result = new int[length];
//add even ints to new array
for (int i = 0, j = 0; i < arr.length; i++)
{
if (arr[i] % 2 == 0) {
result[j++] = arr[i];
}
}

DeleteZero's using Java

I need to finish this code which involves deleting all the zero's stored in the array. I thought it was complete but it won't compile, it's my last line that is dubios and I'm not getting right. Thank you.
public class DeleteZero {
public static int[] array(int[] a) {
int k = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] !=0)
k++;
}
int[] b = new int[k];
int t = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] != 0) {
b[t] = a[i];
t++;
}
}
return b;
}
public static void main (String args[]) {
int[] rand = new int[20];
for (int i = 0; i < 20; i++) {
rand[i] = (int)(Math.random());
}
System.out.println(array(a));
}
}
Few errors.
This would always insert 0 at rand[i] because you are casting Math.random() to int which will always become zero.
rand[i] = (int)(Math.random());
Change it to sth like this. I have written 10 but you can write any number to define the range.
rand[i] = (int)(Math.random()*10);
This line is also wrong:
System.out.println(array(a));
You need to print the array by looping over it, but more importantly your function array() returns a new array, which should be stored somewhere before printing it.
Here is a possible workaround
rand = array(rand);
for (int i=0; i<rand.length; i++){
System.out.println(rand[i]);
}
The compile time error is due to the fact that, in the main method you have created the array named rand and passing the array named a. from the main method call System.out.print(array(rand))
You can try Java 8's Stream, which turns the whole logic to one line return Arrays.stream(a).filter(n -> n!= 0).toArray();
Little fixed your code:
import java.util.Random; // Import Random
public class DeleteZero {
public static int[] array(int[] a) {
int k = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] !=0)
k++;
}
int[] b = new int[k];
int t = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] != 0) {
b[t] = a[i];
t++;
} else {
System.out.println("Skip at position: [" + i + "] because a[i] == "+a[i]+";"); // Display what removed.
}
}
return b;
}
public static void main (String args[]) {
int[] rand = new int[20];
Random rnd = new Random();
for (int i = 0; i < 20; i++) {
rand[i] = rnd.nextInt(11) + 0; // 11-1 = max, 0 = min
}
int[] a = array(rand);
System.out.println(a); // since it prints something like this: [I#106d69c, we should print all elements manually through a loop.
System.out.println("a.length = " + a.length + ", rand length: " + rand.length);
System.out.print("[");
for (int i = 0; i != a.length; i++) {
String space = ", ";
if (i == a.length-1) //if last not print space
space = "";
System.out.print(a[i]+space); // Print all elements
}
System.out.print("]\n");
}
}
Example of output:
Skip at position: [2] because a[i] == 0;
Skip at position: [8] because a[i] == 0;
Skip at position: [10] because a[i] == 0;
Skip at position: [12] because a[i] == 0;
Skip at position: [16] because a[i] == 0;
[I#106d69c
a.length = 15, rand length: 20
[6, 8, 1, 8, 7, 1, 3, 5, 3, 8, 5, 2, 7, 2, 8]

Create a new array containing the index of every occurrance of a target value

I'm trying to make a method that creates a new array containing the index of every occurrence of a target value. I have to use 2 loops for this. The first counts how many times the target occurs. Then create the new array, to hold this many indexes. Then the second loop puts the indexes into the new array.
I've written the code below, but it throws java lang Array Out Of Bound Exception:5, on the line result [ i ] = f [ i ] ;
public class FindAll {
public FindAll() {
int a[] = {7, 8, 9, 9, 8, 7};
print(findAll(a, 7));
print(findAll(a, 2));
}
public void print(int p[]) {
System.out.print("{");
int i;
for (i = 0; i < p.length - 1; ++i) {
System.out.print(p[i] + ", ");
}
System.out.print(p[i]);
System.out.print("}");
}
public int[] findAll(int f[], int target) {
int count = 0;
for (int i = 0; i < f.length; ++i) {
if (f[i] == target) {
count++;
}
}
int result[] = new int[count];
for (int i = 0; i < f.length; ++i) {
if (f[i] == target) {
result[i] = f[i];
}
}
return result;
}
}
Try this
int result[] = new int[count];
int index = 0;
for (int i = 0; i < f.length; i++)
{
if (f[i] == target){
result[index] = f[i];
index++;
}
}
Replace the findAll function with this
public int[] findAll(int f[], int target) {
int count = 0;
for (int i = 0; i < f.length; ++i) {
if (f[i] == target)
count++;
}
if(count == 0) return null;
int result[] = new int[count];
for (int i = 0, curr = 0; i < f.length; ++i) {
if (f[i] == target)
result[curr++] = i;
// Here you have to store the index not the value
}
return result;
}
Add these lines to print method to avoid an exception when the array is null
if(p == null || p.length == 0){
System.out.println("P is null or empty");
return;
}
It will work fine!
The result array you are creating is the size of the number of occurrences of the target, not the size of the original array.
public int[] findAll(int f[], int target)
{
int count = 0;
for (int i = 0; i < f.length; ++i)
{
if (f[i] == target)
count++;
}
int result[] = new int[count]; // This is the size of number of occurrences of target
for (int i = 0; i < f.length; ++i) // 'i' will go up to size of original array
{
if (f[i] == target)
result[i] = f[i]; // You are trying to put the element of the original array in to the same index of your result!?
}
return result;
}
Instead, you need to be adding, for each target element, it's index:
int resultIndex = 0;
for (int i = 0; i < f.length; i++) {
if ( f[i] == target ) {
result[n] = i;
n++;
}
}

remove duplicates in array using method

I'm trying to remove duplicate numbers from an array using a method but, unfortunately I can not solve it. This what I have done so far:
//method code
public static int[] removeDuplicates(int[] input){
int []r=new int[input.length];
for (int i = 0; i < input.length; i++) {
for (int j = 0; j < input.length; j++) {
if ((input[i]==input[j]) && (i != j)) {
return r;
}
}
}
return r;
}
The easiest thing to do is add all elements in a Set.
public static int[] removeDuplicates(int[] input){
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i < input.length; i++) {
set.add(input[i]);
}
//by adding all elements in the Set, the duplicates where removed.
int[] array = new int[set.size()];
int i = 0;
for (Integer num : set) {
array[i++] = num;
}
return array;
}
You may do it this way:
public static int[] removeDuplicates(int[] input){
boolean[] duplicate = new boolean[input.length];
int dups = 0;
for (int i = 0; i < input.length; i++) {
if(duplicate[i])
continue;
for (int j = i + 1; j < input.length; j++) {
if ((input[i]==input[j])) {
duplicate[j] = true; // j is duplicate
++dups;
}
}
}
int[] r = new int[input.length] - dups;
int index = 0;
for(int i = 0; i < input.length; ++i)
r[index++] = input[i];
return r;
}
It can also be done in O(n log n). C++ code
If you don't want duplicates in your collection, well you shouldn't be using an Array in the first place. Use a set instead and you will never duplicates to remove in the first place.
If you only "sometimes" want no duplicates, well you better explain your situation further.

Categories