I'm working on implementing a java method based on this correlation formula:
(f * g)[n] = ∑ f[n+m] * g[m],
the lower bound of the summation
is m = 0, and the upper bound is M - 1,
where f is an array of size N
and g is an array of size M.
(f * g)[n] is an array of size N - M + 1
So for example if we have these arrays:
f = {1, 2, 3, 4}, g = {10, 20}
The result is this array:
(f * g)[n] = {1(10) + 2(20), 2(10) + 3(20), 3(10) + 4(20)}
= **{50, 80, 110}**
What I need to do is convert this into Java code. I'm starting by trying to write the code for this example, and then later come up with a more general case. Unfortunately I'm stuck on some of the Java syntax. This is what I currently have:
public static void main(String[] args) {
double[] array1 = new double[] {1, 2, 3, 4, 5};
double[] array2 = new double[] {10, 20};
double[] array3 = new double[3];
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array2.length; j++) {
double pos = array1[i];
double multiply = pos * array2[j];
array3[i]= pos * multiply;
}
}
System.out.print(Arrays.toString(array3));
}
I'm fairly certain the problem is with
array3[i] = pos * multiply;
Essentially what I'm trying to do is to store the multiplication in array3's first index. Then as the loop goes on store it into the second and then third index. I know I'm doing it wrong, but I'm not sure how to approach it, and a third for loop seems confusing and impractical (and I'm not even sure if it would work). Thank you!
You're not setting the output array to the correct length, it needs to be calculated based on the two input lengths (per your N - M + 1) and not hard coded to three. [although I note that with your updated question that three was actually the correct number]
That is also the number of outer iterations you must make. Your out-of-bounds exception is being caused by your iteration from 0 .. N - 1 without taking M into account.
Your are also failing to actually perform any summation. You should set array3[i] to zero as the first operation inside the first loop [*] and then add the multiplication term inside the inner loop.
static double[] array_product(double[] a, double[] b) {
int n = a.length - b.length + 1;
double[] result = new double[n];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < b.length; ++j) {
result[i] += a[i + j] * b[j];
}
}
return result;
}
public static void main(String[] args) {
double[] array1 = new double[] {1, 2, 3, 4};
double[] array2 = new double[] {10, 20};
double[] result = array_product(array1, array2);
System.out.print(Arrays.toString(result));
}
[*] although the Java language spec guarantees that a new array is set to 0.0, it's not a bad idea to do it explicitly both for clarity of the code and in case the code is ported to a language which does not make that guarantee.
Related
I'm trying to get the N smallest numbers (given by the user) in an array without using methods like sort()... in the last step, I keep getting only the smallest values and 0 for the rest.. where's the problem?
//1- Scanner to take inputs
Scanner input = new Scanner(System.in);
//2- Take the array size as input and store it in "sizeOfArr" var
System.out.print("Enter the array size: ");
int sizeOfArr = input.nextInt();
//3- Assign the input as an array size
int array[] = new int[sizeOfArr];
//4- Looping on the array and update its values by inputs taken from the user
for(int i = 0; i < array.length; i++) {
System.out.print("Enter "+ (i+1) + "-st element: ");
array[i] = input.nextInt();
}
//5- Print out the array after convert it to String
System.out.println(Arrays.toString(array));
//6- Find the smallest element in the array and print it
int minVal = array[0];
for(int i = 0; i < array.length; i++) {
if (array[i] < minVal) {
minVal = array[i];
}
}
// System.out.println(minVal);
//7- Find the (n) smallest of number defined by the user
System.out.print("Enter the number of smallest numbers do you want: ");
int n = input.nextInt();
//8- new array to store n smallest numbers
int smallestNums[] = new int[n];
//9- trying to loop on the original array n times
int counter;
for(int i = 0; i < n ; i++) {
//10- trying to loop on the original array to store the smallest values in smallestNum[] array.
for(int j = 0; j < array.length; j++) {
smallestNums[i] = minVal;
}
if(smallestNums[i] == smallestNums[i]) {
break;
}
}
System.out.println(Arrays.toString(smallestNums));
Here is one way. Just do a partial sort with the outer loop limit equal to the number of items required. This is variant of the selection sort. This example, varies n in the outer list for demo purposes.
int[] array = { 10, 1, 5, 8, 7, 6, 3 };
for (int n = 1; n <= array.length; n++) {
int[] smallest = getNSmallest(n, array);
System.out.printf("smallest %2d = %s%n", n,
Arrays.toString(smallest));
}
prints
smallest 1 = [1]
smallest 2 = [1, 3]
smallest 3 = [1, 3, 5]
smallest 4 = [1, 3, 5, 6]
smallest 5 = [1, 3, 5, 6, 7]
smallest 6 = [1, 3, 5, 6, 7, 8]
smallest 7 = [1, 3, 5, 6, 7, 8, 10]
Here is the method. The first thing to do is copy the array so the
original is preserved. Then just do the sort and return array of smallest elements.
public static int[] getNSmallest(int n, int[] arr) {
int[] ar = Arrays.copyOf(arr, arr.length);
int[] smallest = new int[n];
for (int i = 0; i < n; i++) {
for (int k = i + 1; k < ar.length; k++) {
if (ar[i] > ar[k]) {
int t = ar[i];
ar[i] = ar[k];
ar[k] = t;
}
}
smallest[i] = ar[i];
}
return smallest;
}
For this task, you don't have to sort the whole array. Only a group of N elements has to be sorted. I.e. only a partial sorting is required.
Below, I've provided two implementations for this problem. The first utilizes only plane arrays and loops, the second makes use of the PriorytyQueue.
The first solution maintains a variable pos which denotes the position in the result array which isn't assigned yet. Note that the default value for an element of the int[] is 0. It's important to be able to distinguish between the default value and a zero-element from the given array. Hence we can't rely on the values and have to track the number of elements that are assigned.
Every element of the source array gets compared with all the elements of the result array that are already assigned. The new element will be added to the result array in two cases:
nested loop has reached an unoccupied position pos in the result array;
an element in the result array that is greater than the next element from the given array has been found.
In the first case, a new element gets assigned the position denoted by pos. In the second case, a new element has to be inserted
nested loop iterates over the given array at the current position i and all elements must be shifted to the right. That's what the method shiftElements() does.
The First solution - Arrays & Loops
public static int[] getSmallest(int[] arr, int limit) {
int[] result = new int[Math.min(limit, arr.length)];
int pos = 0;
for (int next: arr) {
for (int i = 0; i < Math.min(pos + 1, result.length); i++) {
if (i == pos) result[i] = next;
else if (result[i] > next) {
shiftElements(result, next, i, Math.min(pos + 1, result.length));
break;
}
}
pos++;
}
return result;
}
private static void shiftElements(int[] arr, int val, int start, int end) {
int move = arr[start];
arr[start] = val;
for (int i = start + 1; i < end; i++) {
int temp = arr[i];
arr[i] = move;
move = temp;
}
}
Maybe you'll be more comfortable with the first version, but if you are somehow familiar with the Collections framework, then it's a good time to get acquainted with PriorytyQueue. In the nutshell, this collection is backed by an array and maintains its element in the same order as they were added, but when an element is being deleted collection retrieves the smallest one according to the natural order or based on the Comparator, which can be provided while instantiating the PriorytyQueue. It uses a sorting algorithm that is called a heapsort which allows removing a single element in O(log N) time.
The Second solution - PriorytyQueue
public static int[] getSmallestWithPriorityQueue(int[] arr, int limit) {
Queue<Integer> queue = new PriorityQueue<>();
populateQueue(queue, arr);
int[] result = new int[Math.min(limit, arr.length)];
for (int i = 0; i < result.length; i++) {
result[i] = queue.remove();
}
return result;
}
private static void populateQueue(Queue<Integer> queue, int[] arr) {
for (int next: arr) {
queue.add(next);
}
}
main & utility-method to generate an array
public static void main(String[] args) {
int[] source = generateArr(100, 10);
System.out.println("source : " + Arrays.toString(source));
int[] result1 = getSmallest(source, 3);
System.out.println("result(Arrays & Loops) : " + Arrays.toString(result1));
int[] result2 = getSmallestWithPriorityQueue(source, 3);
System.out.println("result(PriorityQueue) : " + Arrays.toString(result2));
}
public static int[] generateArr(int maxVal, int limit) {
Random random = new Random();
return IntStream.generate(() -> random.nextInt(maxVal + 1))
.limit(limit)
.toArray();
}
output
source : [61, 67, 78, 53, 74, 51, 50, 83, 59, 21]
result(Arrays & Loops) : [21, 50, 51]
result(PriorityQueue) : [21, 50, 51]
Randomized select allows to find k-th ranked element in linear time on average.
It alters the input order, so practically, it makes sense to just sort and return k-th element of the sorted array. Especially if there are several such calls on the given input array.
How can I modify the methods cutRod and bottomUpCutRod to hold lengths that are bigger than the array length. For example, currently p has length 11, how can I cut the rod of length 15, 20 , etc, having this same array. For example
p = {0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30};
if I call cutRod(p,10), I get 30, but it crashes of course in cutRod(p,15) or
cutRod(p,20). (same applies for bottomUpCutRod). Any ideas how to do this?. This is dynamic programming problem, my idea to implement bottomUpCutRod method is to traverse p and for each element calculate every permutation of itself and its neighbors and update if necessary the resulting array, r.
public class Main {
private static final double MINUS_INFINITY = Double.NEGATIVE_INFINITY;
public static void main(String[] args) {
// price array
double[] p = {0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30};
// test cutRod
cutRod(p,10);
// test bottomUpCutRod
bottomUpCutRod(p,10);
}//end of main
// an optimal cut for a rod of length n
// p is the price array
// use recursion
private static double cutRod(double[] p, int value) {
double[] r = new double[value+1];
double out = 0;
// initialize r to NEGATIVE_INFINITY;
for (int i = 1; i < r.length; i++)
r[i] = MINUS_INFINITY;
// call the helper method
out = helpCutRod(p,r.length-1,r);
// print r
System.out.println("Result ");
System.out.println("r[" + (r.length-1) + "] = " + r[r.length-1]);
return out;
}//end of method
// helpCutRod computes an optimal cut for a rod
// p is the price array and r[i] is the optimal cut for a rod of length i
// n is the length of the rod that is currently being computed
private static double helpCutRod(double[] p, int n, double[] r) {
double q = MINUS_INFINITY;
if (r[n] >= 0) // the whole r was computed
return r[n];
if (n == 0)
q = 0;
else {
for (int i = 1; i <= n; i++) {
q = RodCutting.max(q, p[i] + helpCutRod(p,n-i,r));
}
r[n] = q;
}
return q;
}
// use the bottom-up approach
// do NOT use recursion
private static double bottomUpCutRod(double[] p, int len) {
// r[i] is the optimal cut for a rod of length i
double[] r = new double[len+1];
r[0] = 0;
for (int j = 1; j < p.length; j++) {
// compute r[j]
double q = MINUS_INFINITY;
// r[j] is the maximum over i of p[i] + r[j-i]
// where 1<= i <= j
for (int i = 1; i <= j; i++)
q = max(q, p[i] + r[j-i]);
// update value of r[j]
r[j] = q;
}//end of for outer
// print r
System.out.println("The r array from the bottomUpCutRod:");
System.out.println("r[" + len + "] = " + r[len]);
return r[len] ;
}//end of method
public static double max(double a, double b){
if(a<=b){
return b;
}else{
return a;
}
}//end of max
}//end of class
If I understand the rod cutting problem correctly, your price array, p, tells the prices at which you can sell rod pieces of lenghts 0 through p.length - 1. So if the array length is 11, you know the prices of pieces up to length 10 even if you have an inital rod of length 15, 20 or 30. Since you don’t know the prices for lengths 11 and above, I assume you can safely set them to 0. I would then expect the algorithm to cut up your rod into pieces for which you know a positive price.
If all of this is correct, the solution is easy. To calculate, say, cutRod(p, 15), first do
p = Arrays.copyOf(p, 15 + 1);
This will copy p into a new array with indices 0 through 15, padded with zeores. Now run your methods. Similarly for other initial lengths, of course.
With this modification, your program prints for a rod length of 15:
Result
r[15] = 43.0
The r array from the bottomUpCutRod:
r[15] = 43.0
I assume it’s found pieces at 10, 3 and 2 yielding prices 30 + 8 + 5 = 43, but I haven’t checked.
EDIT: If the rod is very much longer than the price array, it is probably wasteful to have it calculate results with cuts longer than the maximum of the price array. So instead of the above quick fix, it is in fact possible to modify your methods to accept a shorter price array and a longer initial rod.
In the recursive helpCutRod(), change the for loop to:
for (int i = 1; i <= Math.min(n, p.length - 1); i++) {
This will make sure that only pieces for which we have prices will be considered.
For bottomUpCutRod(), two changes are needed:
The first for loop needs to run until j equals len:
for (int j = 1; j < r.length; j++) {
And again, the inner for loop should not pass the bounds of p:
for (int i = 1; i <= Math.min(j, p.length - 1); i++)
With these three modifications instead of the extension of the p array, the program prints the same results as above.
Im using Eclipes Android.
So here's my array1, and I want it to transfer to another array(array2) randomly.
I've been working on it for hours but I can't get it right.
int array1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,26,27,28,29,30,
31,32,33,34,35,36,37,38,39,40,
41,42,43,44,45,46,47,48,49,50};
I want to transfer it to my new array, array2 randomly.
I'm still new to java and still learning.Thanks.
Random randomGenerator = new Random();
j = 0;
for (int idx = 1; idx <= 10; ++idx){
{
int randomInt = randomGenerator.nextInt(array1.length());
array2[j] = array1[randomInt];
j++;
}
}
this is just an idea proceed accordingly.
Here's what I would suggest that you do to randomize an array:
for(int i = 0; i < array1.length; i++) {
int random = (int)(Math.random() * 49 + 1);
int temp = array1[random];
array1[random] = array1[i];
array1[i] = temp;
}
This should randomly shift values around. In each iteration, a random number's element will switch places with the iteration index's element. In you case, you'll have to copy the array into another array before doing the above code.
I want to reverse the integers in Array 's'. I can't figure out why the output is reversing on itself. Link for code
http://ideone.com/REuGYt
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
int[] s = {4,5,6,7,8};
for (int x = 0; x < s.length; x++) {
s[x] = s[(s.length - x) -1];
System.out.println(s[x]);
}
}
}
//outputs
8
7
6
7
8
You are only copying the right side values to the left side values; you aren't switching the values from both sides. Instead of just copying the right side to the left side, swap their values. Replace
s[x] = s[(s.length - x) -1];
with
int temp = s[x];
s[x] = s[(s.length - x) -1];
s[(s.length - x) -1] = temp;
Additionally, you will need to stop your for loop halfway through the array, before x reaches s.length/2, or else the second half will swap the values back to their original locations.
Try this:
List<Integer> reversed = Arrays.asList(4,5,6,7,8);
Collections.reverse(reversed);
It'll build a collection, then reverse it.
You're changing the values in the array as you iterate. When you get halfway through your array you begin to print out values that you previously wrote in. This makes it appear mirrored. One fix is by using two arrays:
int[] s = {4, 5, 6, 7, 8};
int[] rev = new int[s.length];
for (int x = 0; x < s.length; x++) {
rev[x] = s[(s.length - x) - 1];
System.out.println(rev[x]);
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am trying to send array to method and checking the array integer values whether they are prime or not and then storing all prime numbers in new array and sending it back.
import java.util.Arrays;
public class FunPrime {
public static int[] calculate(int[] arr) {
int arr2[] = {};
int count = 0;
for (int i = 0, m = 0; i < arr.length; i++) {
for (int j = 1; j <= arr[i]; j++) {
if (arr[i] % j == 0) {
count++;
}
if (count > 2)
break;
}
if (count <= 2) {
arr2[m] = arr[i];
}
}
return arr2;
}
public static void main(String args[]) {
int no[] = { 1, 4, 5, 6, 7, 8, 11, 22, 43 };
System.out.println(Arrays.toString(calculate(no)));
}
}
In Java if we write
int array = new int [10] ;
Then its a dynamic initialization and not static. Therefore you need to allocate memory statically by
int array = { 1, 4, 5, 6, 7, 8, 11, 22, 43 };
also in future if you want to initialize an array to zero then you can use
int arr[] = new int[10];
for(int i=0;i<arr.length;i++)
arr[i] = 0;
There are, at least, three things wrong...
First...
int arr2[] = {};
Is creating an empty array with no positions available to store any content, this means the moment you try and access any element within it, you will get an ArrayIndexOutOfBoundsException
You should initialise the array to the desired length, for example...
int arr2[] = new int[arr.length];
Two...
The value of count is never re-initialised after it is used, this means that it keeps getting incremented on each loop, meaning it will only ever be capable of reporting the first successful match, instead, you should initialise the count back to 0 on each loop, for example...
for (int i = 0, m = 0; i < arr.length; i++) {
count = 0;
for (int j = 1; j <= arr[i]; j++) {
Third...
m is never incremented, meaning that you are always storing the sucessful match to the first element position in the arr2, don't forget to increment the value, for example...
arr2[m] = arr[i];
m++;
Bonus
The problem with this is, this will return 0 for the elements that don't match, for example...
[1, 5, 7, 11, 43, 0, 0, 0, 0]
This might not be desired
You can "trim" the result using System.arraycopy, but you will need to make one minor change first. The m value indicates the number of matches, this is useful, but because it's declared in the for-loop, we can't access it outside the for-loop, so instead, you need to declare it outside of the for-loop, for example...
int m = 0;
for (int i = 0; i < arr.length; i++) {
This then allows us to declare a third array which will hold the final results we want, for example...
int[] arr3 = new int[m];
System.arraycopy(arr2, 0, arr3, 0, m);
return arr3;
Which will now output...
[1, 5, 7, 11, 43]
Instead of...
[1, 5, 7, 11, 43, 0, 0, 0, 0]
You really want to use new to allocate that memory before you start using references. I also think you can do away with the x = x and x = 1; then you can stop your loop with a break. That should be quicker. Something like
for (int y = 2; y < x; y++) if (x % y == 0) { result = true; break; }
How to find number of prime numbers between two integers
You initialize your second array with zero elements
int arr2[] = {};
Arrays do not grow, so arr2[0] = someValue will give you an ArrayIndexOutOfBounds since there is no first element.
When you create a new array, you should specify it's size.
int arr2[] = {};
This creates an array of size 0. You probably get an ArrayIndexOutOfBoundsException
This is your solution..this will print
[1, 5, 7, 11, 43]
import java.util.ArrayList;
public class FunPrime {
public static ArrayList<Integer> calculate(int[] arr) {
ArrayList<Integer> l = new ArrayList<Integer>();
for (int i = 0; i < arr.length; i++) {
if(isPrime(arr[i]))
{
l.add(arr[i]);
}
}
return l;
}
static boolean isPrime(int n) {
for(int i=2;i<n;i++) {
if(n%i==0)
return false;
}
return true;
}
public static void main(String args[]) {
int no[] = { 1, 4, 5, 6, 7, 8, 11, 22, 43 };
System.out.println(calculate(no));
}
}