Remove element from an array (code-specific) - java

The user enters x-amount of integers, which are stored in an array ('dataA'). The average of the data is calculated, and the element, which is furthest should be removed ('outlier'). I don't know how to remove the element and need to know.
Also, the program removes one outlier, it calculates the new average and removes the next outlier until there is one element left.
public static Scanner sc1 = new Scanner(System.in);
public static int dataN = sc1.nextInt();//number of data elements
public static double[] dataA = new double[dataN];//array storing elements
for(int index = 0; index<dataA.length; index++)//increments index
{
double lengthA = dataA.length;//length of array
double avg = sum/lengthA;//avg of elements
double outlier = dataA[0];//outlier
double index_outlier = 0;//index of outlier
double dif_in = Math.abs(avg - dataA[index]);//difference of avg & element
double dif_out = Math.abs(avg - outlier);//difference of avg & outlier
if(dif_in > dif_out)
{
outlier = dataA[index];
index_outlier = index;
}

You can try to swap the outlier with last element of Array and continue with array but consider one less element. In case you are fine with it then you can use Array like:
public static void main(String[] args) throws FileNotFoundException {
double[] dataArray = new double[] {1.5,2.5,3.5,4.5,7.5,8.5,2.5};
int arraySizeToConsider = dataArray.length;
double outlier;
int index_outlier;
double avg;
double diffInOutlierAndAvg;
while(arraySizeToConsider > 0) {
outlier = dataArray[0];
index_outlier = 0;
avg = computeSum(dataArray,arraySizeToConsider) / (arraySizeToConsider);//avg of elements
diffInOutlierAndAvg = Math.abs(avg - outlier);
// find outlier
for(int index = 0; index<arraySizeToConsider; index++)//increments index
{
if(Math.abs(avg - dataArray[index]) > diffInOutlierAndAvg) {
outlier = dataArray[index];
index_outlier = index;
}
}
double temp = dataArray[arraySizeToConsider -1];
dataArray[arraySizeToConsider -1] = outlier;
dataArray[index_outlier] = temp;
arraySizeToConsider = arraySizeToConsider -1;
System.out.println("Average: " + avg + " Outlier: " + outlier + " index " + index_outlier + " array size to consider: " +arraySizeToConsider);
}
}
private static double computeSum(double[] array, int arraySizeToConsider) {
double sum = 0;
for (int i = 0; i < arraySizeToConsider; i++) {
sum = sum + array[i];
}
return sum;
}
And here is the output:
Average: 4.357142857142857 Outlier: 8.5 index 5 array size to consider: 6
Average: 3.6666666666666665 Outlier: 7.5 index 4 array size to consider: 5
Average: 2.9 Outlier: 4.5 index 3 array size to consider: 4
Average: 2.5 Outlier: 1.5 index 0 array size to consider: 3
Average: 2.8333333333333335 Outlier: 3.5 index 2 array size to consider: 2
Average: 2.5 Outlier: 2.5 index 0 array size to consider: 1
Average: 2.5 Outlier: 2.5 index 0 array size to consider: 0
There are some more optimizations that I have left to you to figure out.
Hint: Do we need to compute sum every time we find an outlier ;)?

Best solution would be to create a new array that copies the elements from the previous one except for the one you want to delete (with a for loop and an array with 1 less space than yours) and then set your original array as the new one.

Since you need a variable size data structure use a LinkedList instead of primitive array.
Also a better solution to do this will be as follows:
1) Store all the values in a LinkedList. Sort it while add elements to the list using insertion sort or sort it after adding all elements using Collections.sort(list).
2) Find the average. This can be done while adding the elements in the list. No need to iterate over the list again.
3) Since all the values are in sorted manner, the outlier will be either the first or the last element in the LinkedList. Compare the diff_first and diff_last and remove the greater.
4) Recompute the average. For this you can use a very simple equation:
new_avg = ((avg*l)-outlier_value)/(l-1);
where l = number of values for which avg was calculated.
5) Repeat step 3 and 4 until only 1 element is left in the LinkedList.

Related

Choose one in pair from array and find minimum total

You receive an array of integers and must choose one value from each pair of adjacent values. For example, given {1,0,5} you can pick 1 and 5 or just 0. The goal is to find the minimum total sum you can get from all the chosen values, print it, and print each chosen value from the array.
For example, given {1,0,5} you want to choose 0 since it's the lowest in the pairs (1,0) and (0,5), and the minimum total sum is 0.
Another example: given {10,30,90,50,30} the minimum sum is 30 + 50 = 80 and we made sure that for each pair of adjacent values at least one was chosen (10,30), (30,90), (90,50), (50,30).
I used dynamic programming to find the minimum total sum, but I'm not sure how to print each chosen value to create that sum.
public static void main(String[] args) {
// Define the input array
int[] arr = {50, 30, 40, 60, 10, 30, 10};
// Define the array to store the minimum sum for each index
int[] dp = new int[arr.length];
// Initialize the first element of the dp array
dp[0] = arr[0];
dp[1] = arr[1];
// Loop over the input array from the second index to the last index
int choice1 = 0, choice2;
for(int i = 2; i<arr.length; i++) {
// Choose the previous index and add its minimum sum to the current element
choice1 = dp[i-1] + arr[i];
// Choose the index before the previous index and add its minimum sum to the current element
choice2 = dp[i-2] + arr[i];
// Compare the two choices and choose the one with the lower sum
dp[i] = Math.min(choice1, choice2);
}
// Print the minimum sum and the chosen values
if(dp[arr.length - 1] > dp[arr.length - 2]) {
System.out.println(dp[arr.length - 2]);
}else {
System.out.println(dp[arr.length - 1]);
}
}

Removing all the zeros from an array using scanner

I needed an array that takes integers from a user until '0' is entered; then it prints average, max and min. I wrote an array with 700 elements and it breaks. When I input 0 everything works well. The problem is when I input 0 it takes 0 as an element. I solved that somehow so it can calculate the average correctly but it still takes some 0 from somewhere. For example, I input 8 and then 3 and then 0, and the output is the average is 4.000000, the biggest one is 5, the smallest one is 0, but the smallest one should be 3.
I guess it's because the remaining 697 elements are considered as 0.
I found a lot of answers for this problem but I want to solve it without copying the array or creating a new one. Is there anything that I can do to fix this without adding an array or another for loop or something? Like a line that means 'when the 0 is entered remove all remaining elements and don't use them for anything'?
import java.util.Scanner;
import java.util.stream.IntStream;
public class PlayingWithNumbers2 {
private static Scanner input;
public static void main(String[] args) {
input = new Scanner(System.in);
int[] array = new int[700];
System.out.println("Enter numbers enter 0 to end");
int i;
int max = array[0];
int min = array[0];
int a = array[0];
for (i = 0; i < array.length; i++) {
a=input.nextInt();
if(a==0){
break;
}
array[i] = a;
if(array[i]>max)
max = array[i];
else if(array[i]<min)
min = array[i];
}
double sum = IntStream.of(array).sum();
double Ave = sum/i;
System.out.printf(" The Average is %f \n the biggest one is %d \n the smallest one is %d", Ave, max, min);`
}
}
The problem with the min/max is both are initialized to array[0] which means both are initialized to '0' and so the min check will always keep it at 0 as it is below anything you enter. You also need to remove the else condition. Try this
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
then inside the loop change the checks to be
if(array[i]>max)
max = array[i];
if(array[i]<min)
min = array[i];
You can use range():
double sum = IntStream.of(array).range(0, i).sum();
double Ave = sum/(i-1);
In this way, you'll be counting only numbers that are truly entered by the user and leave 'fake' 0 out of your sum.

JAVA ArrayIndexoutofBoundException issue

A perfect number is one that is the sum of its factors, excluding itself. The 1st perfect number is 6 because 6 = 1 + 2 + 3. The 2nd perfect number is 28 which equals 1 + 2 + 4 + 7 + 14. The third is 496 = 1 + 2 + 4 + 8 + 16 + 31 + 62 + 124 + 248. In each case, the number is the sum of all its factors excluding itself.
Write a method named henry that takes two integer arguments, i and j and returns the sum of the ith and jth perfect numbers. So for example, henry (1, 3) should return 502 because 6 is the 1st perfect number and 496 is the 3rd perfect number and 6 + 496 = 502.
I have done this far:: but this is showing ArrayIndexOutOfBoundException at this line temp[index] = j; please help me to solve this OutOfBound issue, Thanks..
public static int henry (int a, int b){
List<Integer> arr = new ArrayList<Integer>();
int henryNumber = 0;
for(int i=4;;i++){
List<Integer> temp = new ArrayList<Integer>();
int sum = 0;
for(int j = 1; j<i; j++){
if(i%j == 0 ) { temp.add(j); }
}
for (Integer item : temp) { sum+=item; }
if(sum == i) arr.add(i);
if(arr.size() == b) {
henryNumber = arr.get(a-1) + arr.get(b-1);
break;
}
}
return henryNumber;
}
int[] temp = {};
This sets temp to an array of 0 elements. So when you try to access temp[index] where index is = to 0 its out of bounds because the array doesn't have even a single element
You would need to create an array of x number elements by doing:
int[] temp = new int[x];
and then you can set the value at each of the indicies to whatever value you want.
An array has a fixed length as soon as it it created, and that length cannot be changed.
int[] temp = {};
This creates an empty array. Its length is zero. You can't change that, you can't add any items to it.
temp[index] = j;
This tries to put something in the temp array. However, as I said, the array is empty, its length is zero, so any value of index would be out of bounds.
Using a List (which is commented out in your source) will allow you to create a growing collection of elements. Alternatively, you have to think of a proper size for your array, that will hold all the elements you'll be using, and use that size when you create the array.
Try doing
int[] temp=new int[i];
instead of
int[] temp={};
I have never assigned an array like this before.

calculate the average value across indicies of a hash map

I tried writing this code to test out my idea on how to calculate the average value across like indices of a hash map.
i.e. for each array contained within the hashmap if the first value for the first array was 2, and the first value for the second array was 4 , and the first value for the third array was 3, I want to assign the value of (4+3+2/3)= 3 to the final double[] array for the first index, and so on for all the indices 2 through n.
int Size = 3;
double[] AVERAGED_WEIGHTS = new double[Size];
//store weights to be averaged.
Map<Integer,double[]> cached_weights = new HashMap<Integer,double[]>();
double[] weights = new double[Size];
int iteration = 0;
do
{
weights[iteration] = Math.floor(Math.random() * 10000) / 10000;
iteration++;
//store weights for averaging
cached_weights.put( iteration , weights );
}
while (iteration < Size);
//calc averages
for (Entry<Integer, double[]> entry : cached_weights.entrySet())
{
int key = entry.getKey();
double[] value = entry.getValue();
AVERAGED_WEIGHTS[ key - 1 ] += value[ key - 1 ];
if (key == iteration)
{
AVERAGED_WEIGHTS[ key - 1 ] /= key;
}
}
for(int i = 0; i < weights.length; i++)
{
weights[i] = AVERAGED_WEIGHTS[i];
}
This mimics the structure of the original program wherein the weights are populated through a do while loop. This code is broken though and does not sucessfully perform the operation described above. I've been searching online and trying different ways to fix it but I've not been able to solve it. Perhaps someone can spot my faulty logic.
Maybe I misunderstood you, but you are not computing the average because for each array in your map, you are not taking into account all its positions. You are using the key and that makes absolutely no sense. Anyways, your code is very confusing. What you need to do is simply one loop inside the other. One going through the arrays and another going through the elements of each array. A way to compute the average is the following (in a didactic way):
//compute averages
double[] sums = new double[size];
double[] averages = new double[size];
for (Entry<Integer, double[]> entry : cachedWeights.entrySet()) {
double[] value = entry.getValue();
for(int pos=0; pos < Math.min(size, value.length); pos++){
sums[pos] += value[pos];
}
}
for(int pos=0; pos < size; pos++){
averages[pos] = sums[pos] / cachedWeights.size();
}

errors in java - finding maximum values in an ArrayList

Following is the program I wrote as an answer for the question -
"Now use ArrayList and the Integer wrapper class to store the values and initialize the elements by reading input from console using Scanner class.Extend the program to identify the n maximum values in the ArrayList."
import java.util.ArrayList;
import java.util.Scanner;
public class ArraylistInput {
/**
* #param args
*/
public static void main(String[] args) {
ArrayList<Integer> val = new ArrayList<Integer>();
Scanner in = new Scanner(System.in);
System.out.println("Enter the length of you Array List ");
int nos = in.nextInt();
// Recorrd the input numbers
for (int i = 0 ; i < nos; i++)
{
System.out.println("Enter values for the ArrayList ");
int Input = in.nextInt();
val.add(Input);
}
// Display the arraylist
for (int j = 0; j < nos; j++)
{
int x = val.get(j);
System.out.println("Index " + (j+1) + ": " + x);
}
System.out.println("How meny maximmum values do you want? ");
int max =0; // initial max value
int nmax = in.nextInt(); // number of maximum values
int length = val.size(); // size of the arraylist
// finding the maximum values in ascending order without sorting
for (int h = 1; h <= nmax ; h++)
{
for (int k=0;k < length; k++)
{
if (val.get (k) > max)
{
max = val.get(k);
}
}
System.out.println ("maximmum = " + max);
int z = val.indexOf(max); // removing the higest value after printing
val.remove(z);
}
}
}
Output and Error:
Enter the length of you Array List
3
Enter values for the ArrayList
12
Enter values for the ArrayList
45
Enter values for the ArrayList
8
Index 1: 12 Index 2: 45 Index 3: 8
How meny maximmum values do you want?
2
maximmum = 45
Exception in thread "main" maximmum = 45
java.lang.ArrayIndexOutOfBoundsException: -1 at
java.util.ArrayList.elementData(Unknown Source) at
java.util.ArrayList.remove(Unknown Source) at
ArraylistInput.main(ArraylistInput.java:46)
I would do the following:
Collections.sort(myList, Collections.reverseOrder());
List<Integer> maxn = myList.subList(0, n);
System.out.printf("The maximum %d values are: %s%n", n, maxn);
maxn.clear(); //This clears the sublist and removes its elements from the source list
That would give you a list with the maximun n elements in your list.
You only have a single ArrayList you don't need the nested for loop to find the maximum:
int max = Integer.MIN_VALUE;
for(int i = 0; i < list.size(); i++)
{
current = list.get(i);
if(current > max)
max = current;
}
The nested for loop when you are searching for the maximum tries to access a value in your list that doesn't exist, which is why you are receiving this error.
Your max is never getting assigned and then you are trying to remove a non-existing element from the arraylist. Set max to some value that cannot occur in the list and then check whether it ever got assigned in the loop.
When you remove an element from the list with:
val.remove(z);
You change the size of the list but you don't update your length variable. This causes you to try to access indices beyond the size of the array, resulting in a java.lang.ArrayIndexOutOfBoundsException.
Also, consider saving both the index of the max value and the max value itself. Then, when you go to remove the value, you can use ArrayList.remove() directly without searching the whole list again for the max index (which is what ArrayList.indexOf() will do).

Categories

Resources