Java - Array Shuffle from Array1 to Array 2 - java

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.

Related

How can I get N smallest number in an array?

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 to copy the contents of a set to a two dimensional array in Java?

The idea is to have a two dimensional array NxN where all the elements (numbers from 0 to N*N) are in random positions. To generate the random numbers I used:
// Creates a set so we avoid repetition of generated numbers
Set<Integer> generatedNumbers = new LinkedHashSet<Integer>();
while (generatedNumbers.size() < numberOfElements){
Integer next = rng.nextInt(numberOfElements) ;
generatedNumbers.add(next);
}
Now I need to copy the elements to a two dimensional array. Basically, something like this:
for (Integer number: generatedNumbers){
// Here I'd like to have:
// 1st iteration: board[0][0] = number
// 2nd iteration: board[0][1] = number
// ...
// last iteration: board[3][3] = number
}
where:
board = new int[boardSize][boardSize];
with boardSize = 4 for this particular case.
Btw, if there's a better way to achieve the same but using a different method, I'd be happy to read it.
If I understood correctly you want to randomly distribute numbers from a collection into a 2d array. Here is a working code based on what you gave us that will do just that:
public static Integer[][] getRandomNumbersArray(int base)
{
Random rng = new Random();
int numberOfElements = base * base;
// Let's use a list so we access by index
List<Integer> generatedNumbers = new ArrayList<>();
for (int i = 0; i < numberOfElements; i++)
{
// Generate our random number
Integer next = rng.nextInt(numberOfElements) ;
// Check if the number is already added
if (!generatedNumbers.contains(next)) {
generatedNumbers.add(next);
}
// Number was a duplicate, redo loop cycle
else i--;
}
// Create our board array here
Integer[][] array = new Integer[base][base];
// Index used to access the list
int i1 = 0;
for (int i2 = 0; i2 < base; i2++)
{
// Populate board row
for (int i3 = 0; i3 < base; i3++, i1++) {
array[i2][i3] = generatedNumbers.get(i1);
}
}
return array;
}
public static void main(String[] args)
{
Integer[][] array = getRandomNumbersArray(4);
System.out.println("Here is how our board looks like:");
for (int i = 0; i < array.length; i++) {
System.out.println(Arrays.toString(array[i]));
}
}
Output
Here is how our board looks like:
[8, 7, 11, 3]
[15, 5, 1, 0]
[2, 9, 10, 12]
[13, 4, 6, 14]
Instead of iterating the set on the outside of the loop, consider doing it in reverse. Something along the lines of
Iterator iter = generatedNumbers.iterator()
for (...) {
for (...) {
if (iter.hasNext()) arr[i][j] = iter.next()
else ...
}
}

Java and a Formula

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.

What is wrong in this code for checking if a number is a prime? [closed]

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));
}
}

Replace duplicate numbers with unique numbers from 0-(N-1)

Background:
I have an N-length array of positive random numbers that are certain to contain duplicates.
e.g. 10,4,5,7,10,9,10,9,8,10,5
Edit: N is likely to be 32, or some other power of two about that size.
The Problem:
I am trying to find the fastest way to replace the duplicates with the missing numbers from 0-(N-1). Using the above example, I want a result that looks like this:
10,4,5,7,0,9,1,2,8,3,6
The goal being to have one of each number from 0 to N-1, without just replacing all the numbers with 0-(N-1) (the random order is important).
Edit: It's also important that this replacement is deterministic, i.e. the same input will have the same output (not random).
My solution:
Currently implemented in Java, uses 2 boolean arrays to keep track of used/unused numbers (unique numbers/missing numbers in the range [0,N) ), and has an approximate worst-case runtime of N+N*sqrt(N).
The code follows:
public byte[] uniqueify(byte[] input)
{
boolean[] usedNumbers = new boolean[N];
boolean[] unusedIndices = new boolean[N];
byte[] result = new byte[N];
for(int i = 0; i < N; i++) // first pass through
{
int newIdx = (input[i] + 128) % N; // first make positive
if(!usedNumbers[newIdx]) // if this number has not been used
{
usedNumbers[newIdx] = true; // mark as used
result[i] = newIdx; // save it in the result
}
else // if the number is used
{
unusedIndices[i] = true; // add it to the list of duplicates
}
}
// handle all the duplicates
for(int idx = 0; idx < N; idx++) // iterate through all numbers
{
if(unusedIndices[idx]) // if unused
for(int i = 0; i < N; i++) // go through all numbers again
{
if(!usedNumbers[i]) // if this number is still unused
{
usedNumbers[i] = true; // mark as used
result[i] = idx;
break;
}
}
}
return result;
}
This seems like the fastest I can hope for, but I thought I'd ask the internet, because there are people much more clever than I who may have a better solution.
N.B. Suggestions/solutions do not have to be in Java.
Thank you.
Edit: I forgot to mention that I am converting this to C++. I posted my java implementation because it's more complete.
Use a balanced binary search tree to keep track of used/unused numbers instead of a boolean array. Then you're running time will be n log n.
The most straightforward solution would be this:
Go through the list and build the "unused" BST
Go through the list a second time, keeping track of numbers seen so far in a "used" BST
If a duplicate is found, replace it with a random element of the "unused" BST.
Here is how I would write it.
public static int[] uniqueify(int... input) {
Set<Integer> unused = new HashSet<>();
for (int j = 0; j < input.length; j++) unused.add(j);
for (int i : input) unused.remove(i);
Iterator<Integer> iter = unused.iterator();
Set<Integer> unique = new LinkedHashSet<>();
for (int i : input)
if (!unique.add(i))
unique.add(iter.next());
int[] result = new int[input.length];
int k = 0;
for (int i : unique) result[k++] = i;
return result;
}
public static void main(String... args) {
System.out.println(Arrays.toString(uniqueify(10, 4, 5, 7, 10, 9, 10, 9, 8, 10, 5)));
}
prints
[10, 4, 5, 7, 0, 9, 1, 2, 8, 3, 6]
The fastest way to do this is probably the most straightforward one. I would take a pass through the list of data keeping a count of each distinct value and marking where duplicates appeared. Then it is just a matter of forming a list of unused values and applying them in turn at the places where duplicates were found.
Tempting as it may be to use a C++ List, if speed is of the essence a simple C array is the most efficient.
This program show the principle.
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
int data[] = { 10, 4, 5, 7, 10, 9, 10, 9, 8, 10, 5 };
int N = sizeof(data) / sizeof(data[0]);
int tally[N];
memset(tally, 0, sizeof(tally));
int dup_indices[N];
int ndups = 0;
// Build a count of each value and a list of indices of duplicate data
for (int i = 0; i < N; i++) {
if (tally[data[i]]++) {
dup_indices[ndups++] = i;
}
}
// Replace each duplicate with the next value having a zero count
int t = 0;
for (int i = 0; i < ndups; i++) {
while (tally[t]) t++;
data[dup_indices[i]] = t++;
}
for (int i = 0; i < N; i++) {
cout << data[i] << " ";
}
return 0;
}
output
10 4 5 7 0 9 1 2 8 3 6
My approach would be
1. copy the array to a Set in Java.
Set will automatically remove duplicates in the fastest complexity possible(because Sun Micro has implemented it, generally their approach is the fastest like.. use of TimSort for sorting etc...)
Calculate size() of the set.
the size will give you no of duplicates present.
now copy array 0-n-1 to the same set... the missing values will get inserted.
I think it is even possible with running time n. The idea is to keep track of items used in the original list and additional items used during processing in a separate array. A possible java implementation looks like this:
int[] list = { 10, 4, 5, 7, 10, 9, 10, 9, 8, 10, 5 };
boolean[] used = new boolean[list.length];
for (int i : list) {
used[i] = true;
}
boolean[] done = new boolean[list.length];
int nextUnused = 0;
Arrays.fill(done, false);
for (int idx = 0; idx < list.length; idx++) {
if (done[list[idx]]) {
list[idx] = nextUnused;
}
done[list[idx]] = true;
while (nextUnused < list.length && (done[nextUnused] || used[nextUnused])) {
nextUnused++;
}
}
System.out.println(Arrays.toString(list));
List<Integer> needsReplaced = newLinkedList<Integer>();
boolean[] seen = new boolean[input.length];
for (int i = 0; i < input.length; ++i) {
if (seen[input[i]]) {
needsReplaced.add(i);
} else {
seen[input[i]] = true;
}
}
int replaceWith = 0;
for (int i : needsReplaced) {
while (seen[replaceWith]) {
++replaceWith;
}
input[i] = replaceWith++;
}
This should behave in about 2n. The list operations are constant time, and even though that second loop looks nested, the outer loop runs significantly less than n iterations, and the inner loop will only run a total of n times.
C# but should be easy to convert to java. O(n).
int[] list = { 0, 0, 6, 0, 5, 0, 4, 0, 1, 2, 3 };
int N = list.length;
boolean[] InList = new boolean[N];
boolean[] Used = new boolean[N];
int[] Unused = new int[N];
for (int i = 0; i < N; i++) InList[list[i]] = true;
for (int i = 0, j = 0; i < N; i++)
if (InList[i] == false)
Unused[j++] = i;
int UnusedIndex = 0;
for (int i = 0; i < N; i++)
{
if (Used[list[i]] == true)
list[i] = Unused[UnusedIndex++];
Used[list[i]] = true;
}
Edit: tried to convert it to java from c#. I don't have java here so it may not compile but should be easy to fix. The arrays may need to be initialized to false if java doesn't do that automatically.

Categories