Having issues with an array method - java

Write a method named createDoubles that builds an array of floating point values that represent the squares of the numbers from 10.0 to 13.0, in steps of 0.5, inclusive of both boundaries. The method has no parameters and returns an array of doubles. There are exactly 7 numbers in this array.
I keep trying nut nothing is working. Thanks!
public static double[] createDoubles(){
double[] dArray= new double[7];
double[] squareArray= new double[dArray.length];
for(int i= 0; i< dArray.length-1; i+=0.5){
squareArray[i]= dArray[i]* dArray[i];
}
return squareArray;
}

If you are incrementing i with 0.5, how do you expect array index to work in loop? Can you please double check the code.

Something like this will work. Idea is that array indexes increment in steps of 1 and not 0.5 as your loop is expecting.
public static double[] createDoubles(){
double[] dArray= {10.0,10.5,11.0,11.5,12.0,12.5,13.0};
double[] squareArray= new double[dArray.length];
for(int i= 0; i< dArray.length; i++){
squareArray[i]= dArray[i]* dArray[i];
}
for(double f: squareArray)
System.out.println(f);
return squareArray;
}

Try the following way:
public static double[] createDoubles(){
double[] squareArray= new double[7];
double number = 10.0;
int i=0;
while(number <= 13.0) {
squareArray[i] = number*number;
number = number + 0.5;
i++;
}
}
return squareArray;

You can see the following demo:
int i = 0;
i = i + 0.5;
The i will always be 0.
That means your method will not stop when you invoke it.

Here's one way to do it, but probably not what the teacher wants:
public static double[] createDoubles() {
double[] answer = {10.0, 10.5, 11.0, 11.5, 12.0, 12.5, 13.0 );
// Actually, the above values should be 100,m ... 169.
// but I'm too laze to do the math
return answer;
}
Note that it is never a good idea to increment a loop index by a non-integer value. You might be surprised if you tried your method for increments of 0.1 instead of 0.5.

The reason this code isn't running but isn't working is because java is rounding down the i+=0.5 to i+=0, which is causing i to remain equal to 0, your loop never to exit, and your code not to do anything at all. To fix this part of your code, change the i+=0.5 to i+=1. However, as you do not declare anything in the square array, the resulting array that you return is nothing but 0s. Fix that by defining whatever you want in the d array, and multiplying those values together to create the values in the array you want to return. Or, you could simply declare put each value into the array like so:
for(int i= 0; i<= dArray.length-1; i+=1){
squareArray[i]= Math.pow(10 + (0.5*i), 2);
}

squareArray[integer+double] is not a valid array index.
Array index are always integer.

Related

Why introduce a new array in a method? Why not reuse the parameter?

In the method normalize I input an array say, {1, 2, 3, 4}, and the return is a normalized array, {0.1, 0.2, 0.3, 0.4}.
I know I should introduce a new array in the method (b in the following), but why actually?
public static double[] normalize(double[] a) {
double[] b = new double[a.length];
double sum = 0;
for (int i = 0; i < b.length; i++) {
sum += a[i];
}
for (int i = 0; i < b.length; i++) {
b[i] = a[i]/sum;
}
return b;
}
Input: 1 2 3 4
Output: 0.1 0.2 0.3 0.4
Why is the following wrong:
public static double[] normalize(double[] a) {
double sum = 0;
for (int i = 0; i < a.length; i++) {
sum += a[i];
}
for (int i = 0; i < a.length; i++) {
a[i] = a[i]/sum;
}
return a;
}
Input: 1 2 3 4
Output: 0.1 0.2 0.3 0.4
The difference is that one method updates the input array in place, whereas the other one keeps the array intact and returns a copy.
Neither is wrong(*), both ways have their place, you just need to make sure to the caller knows what is happening.
If you update in-place, you can make that clearer by making the method void instead of returning a (redundant) reference to the same array.
(*) In modern practice, prefer immutable data structures. So unless performance is a real issue, go with the "safer" variant.
In the first case, the original array will stay unmodified when the method returns.
In the second case, the original array will be modified (even when it returns to where it was called), irregardless to whatever array you set the return value to afterward.
Both options can be viable, but it depends on the case and what is expected to happen. However, typically I would expect when you pass a parameter to a method, the parameter will not be modified when the method returns.
Documentation can make it clear that the original array will be modified or if it will not be.
Side Note:
This will not work the same way if you modify a directly, instead of modifying the values contained within:
public static void normalize(double[] a) {
a = new double[5];
}
a will remain unchanged in this case when the method returns.
In my opinion, you are creating a new variable with new values. The method receives one var and returns another var.
It's more reader-friendly.
Explaining the byte code behavior, and the difference of creating a new array or reusing the same input is not what you are asking for I think. Because it is really easy to see the difference.
What I think you are looking for, is a conceptual analysis of the difference. From my perspective, "functions" in any language should be treated as math functions. You give X and Y, and the function returns Z. Imagine you have a rectangle which height = a and width = b. If you want the area of it, you pass a and b and you get A . If you want the perimeter, you pass a and b and you get P.
This makes your code more readable, reusable, more cohesive, more testable.

Error finding largest randomly generated double in ArrayList Java

I'm trying to get a program to work where I generate 1,000,000 random numbers between 0 and 1 and then find and print the largest number.
I've got the generator to work and managed to insert each double generated into an ArrayList but I cannot seem to figure out how to find the largest number in the list. At the moment the current code throws the error "java.lang.IndexOutOfBoundsException".
This is all probably due to me being new to the ArrayList and not being fluent with its commands and how it works but I would really appreciate some help on what I'm doing wrong here as I've been stuck for a while.
import java.util.ArrayList;
import java.util.Random;
public class milran {
public static void main(String[] args) {
Random r = new Random();
ArrayList<Double> myList = new ArrayList<Double>();
for (int i = 1; i<=1000000; i++){
double randomValue = 0.0+(1.0-0.0)*r.nextDouble();
myList.add(randomValue);
}
double max = myList.get(1);
for (int z=2; z<=myList.size(); z++){
double test = myList.get(z);
if (test>max){
max = test;
}
}
System.out.println(max);
}
}
First of all take a look at the docs for java.util.Collections and java.util.ArrayList.
Secondly, the ArrayIndexOutOfBoundsException is being triggered by this...
for (int z=2; z<=myList.size(); z++){
double test = myList.get(z);
...
}
This is because array indexing starts at 0, therefore the last element is myList.size() - 1. In other words, when z = myList.size(), it is out of bounds.
Also, in your first for loop, you are using i = 1; 1 <= 1000000. It makes much more sense to use i = 0; i < 1000000 as you can use i to touch each element in an array (or list).
for( i = 0; i < 1000000; i++ )
{
// do something with myArray[i]
}
Here's what I would do after the values have been inserted...
Sort the array: Collections.sort(myList);
Retrieve the last element: System.out.println( myList.get( myList.size() - 1 ) );
...and that's it.
If you need to implement the actual sort yourself then i'd consider using a primitive double array (double[]) rather than a Collection.
Otherwise, if you are using a collection, you can use a foreach loop.
for( Double d : myList ) // for each Double 'd' in myList
{
// do something with d
}
N.B. Another potential issue with this line in the second loop
double test = myList.get(z);
This automatic conversion from Double (object) to double (primitive) is called unboxing. There will be a performance cost, especially when repeated a million times. In the first loop you are converting the other way (autoboxing) – also a million times.
ArrayList start count its elements from 0. You need to replace myList.get(1) to myList.get(0), int z=2 to int z=1 and z<=myList.size() to z<myList.size().
This line: for (int z=2; z<=myList.size(); z++) { is wrong. It should be for (int z=1; z<myList.size(); z++) {.
This is because arrays and lists are 0 based, so a list of size 2 has 2 elements - index 0 and index 1. Currently you try to index into the element number equal to the size, which does not exist.
Along the same line, myList.get(1); should be myList.get(0);.
This is unrelated to your problem, but this line 0.0+(1.0-0.0)*r.nextDouble(); can be much more easily written as r.nextDouble();. I'm not sure what you were trying to do by doing 0 + 1 - 0.
As others have already pointed out, you have an error in your for-loop condition that causes the index to go out-of-bounds.
One way that you can avoid this in the future is by using Java's for-each loop syntax instead of trying to manage the index yourself.
for (Double test : myList) {
if (test>max){
max = test;
}
}
This syntax makes your intent much clearer than the traditional indexed for syntax and removes a point of potential error (managing the index and the bounds of the list) from your hands.

Shuffling an ArrayList

I'm trying to create a method to randomly shuffle a array of primitives using a Arraylist. I was wondering if the .get(); method was the proper method to use on my Arraylist where on a normal array in a for loop it would just be array[j]; where j is the value in the for loop. Also, I'm not too familiar with Math.random(); and needed some help implementing it in this situation.
public static void selectionShuffle(int[] values) {
ArrayList<Integer> temp=new ArrayList<Integer>(52);
int rando=(int)Math.random()*52+1;
for(int counter=0;counter<temp.size();counter++){
temp.set(rando,(Integer)counter);
}
for(int counter=0;counter<values.length;counter++){
values[counter]=temp.get(counter);
}
}
Collections.shuffle(temp); is what you need
http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#shuffle%28java.util.List%29
What you may want to do is after creating the ArrayList, run a for-loop to add 52 values:
for(int i = 0; i < 52; i++){
temp.add(i);
}
Then do this:
Collections.shuffle(temp);
Print out the result to confirm
Your implementation should ensure that every index is set at least once. Your temp.set(rando,(Integer)counter) sets a random index to the value of counter. Also, you must change the value of rando with every iteration of the loop.
Math.random()
returns a double value with a positive sign, greater than or equal to
0.0 and less than 1.0.
as per Oracle, so when you multiply by 52.0 you get a value between 0 and 51.9 inclusive. When cast to an integer it is truncated to the floor of its value, giving you a range of 0 - 51 inclusive, or the size of your array.

Exception error when printing values from an array in Java

I am trying to pass values into my array using a 2.4 increment over each iteration in my loop. Here is my code:
import java.util.*;
public class RunningArray {
public static void main(String[] args) {
double [] running = new double [10];
int i;
for (i=0; i<running.length; i+=2.4)
running[i]=i;
System.out.println(running[i]);
}
}
But when I try to print (running[i]) I am getting the error
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
at RunningArray.main(RunningArray.java:26)
Can someone please explain why?
The loop counter is fine, the real problem is that because you haven't enclosed running[i]=i; in braces, that's the only statement in the for loop. You're printing running[i] outside the for loop, so i >= running.length (10 in this case).
Exception is self explanatory. value of i is going beyond array length of 10. Print the i value before accessing array value and you will know the issue.
Any reason for i = i+ 2.4?
At any point of time, i should not cross array length of 10.
It is because the variable i is of int type and each time you increment it by 2.4 only 2 is added to its value.
for (i=0; i<running.length; i+=2.4)
System.out.print(i+", ");
Output: 0, 2, 4, 6, 8,
but just before the condition of loop is tested to be false, i is incremented by 2 making its value 10.
when you write the following line without braces it takes the last value of i, that is 10
System.out.println(running[i]);
Since running[i] for i=10 is not available it gives exception.
Write it like this
for (i=0; i<running.length; i+=2.4)
{ running[i]=i;
System.out.println(running[i]);
}
Output:
0.0
2.0
4.0
6.0
8.0
Don't add 2.4 to the value of i, use another variable of double data type and increment it by 2.4 and store it in the array.
double [] running = new double [10];
double d=0.0;
for (int i=0; i<running.length; i++)
{
d+=2.4;
running[i]=d;
System.out.println(running[i]);
}
output:
2.4
4.8
7.199999999999999
9.6
12.0
14.4
16.8
19.2
21.599999999999998
23.999999999999996
you also are instantiating i as a int which means the .4 is being stripped each time. Initialize the variable to a double and it should carry the decimal point as you step through iterations.
double [] running = new double [10];
Double i;
for (i=0.0; i<running.length; i+=2.4)
{
running[i]=i;
System.out.println(running[i]);
}

Weighted sampling with replacement in Java

Is there a function in Java, or in a library such as Apache Commons Math which is equivalent to the MATLAB function randsample?
More specifically, I want to find a function randSample which returns a vector of Independent and Identically Distributed random variables according to the probability distribution which I specify.
For example:
int[] a = randSample(new int[]{0, 1, 2}, 5, new double[]{0.2, 0.3, 0.5})
// { 0 w.p. 0.2
// a[i] = { 1 w.p. 0.3
// { 2 w.p. 0.5
The output is the same as the MATLAB code randsample([0 1 2], 5, true, [0.2 0.3 0.5]) where the true means sampling with replacement.
If such a function does not exist, how do I write one?
Note: I know that a similar question has been asked on Stack Overflow but unfortunately it has not been answered.
I'm pretty sure one doesn't exist, but it's pretty easy to make a function that would produce samples like that. First off, Java does come with a random number generator, specifically one with a function, Random.nextDouble() that can produce random doubles between 0.0 and 1.0.
import java.util.Random;
double someRandomDouble = Random.nextDouble();
// This will be a uniformly distributed
// random variable between 0.0 and 1.0.
If you have sampling with replacement, if you convert the pdf you have as an input into a cdf, you can use the random doubles Java provides to create a random data set by seeing in which part of the cdf it falls. So first you need to convert the pdf into a cdf.
int [] randsample(int[] values, int numsamples,
boolean withReplacement, double [] pdf) {
if(withReplacement) {
double[] cdf = new double[pdf.length];
cdf[0] = pdf[0];
for(int i=1; i<pdf.length; i++) {
cdf[i] = cdf[i-1] + pdf[i];
}
Then you make the properly-sized array of ints to store the result and start finding the random results:
int[] results = new int[numsamples];
for(int i=0; i<numsamples; i++) {
int currentPosition = 0;
while(randomValue > cdf[currentPosition] && currentPosition < cdf.length) {
currentPosition++; //Check the next one.
}
if(currentPosition < cdf.length) { //It worked!
results[i] = values[currentPosition];
} else { //It didn't work.. let's fail gracefully I guess.
results[i] = values[cdf.length-1];
// And assign it the last value.
}
}
//Now we're done and can return the results!
return results;
} else { //Without replacement.
throw new Exception("This is unimplemented!");
}
}
There's some error checking (make sure value array and pdf array are the same size) and some other features you can implement by overloading this to provide the other functions, but hopefully this is enough for you to start. Cheers!

Categories