Is there a way where you can use Math.random to prints the element in a given array?
int[] list = new int[] {1,2,3};
So the output will be like
2,1,3
or
3,1,2
or
2,3,1
Perhaps you can approach it by shuffling your array then print it. If the original should not be modified, you can make a copy and then shuffle the copy.
There are well-known algorithms for shuffling array (or a deck of cards). One can be found here. An implementation in java looks like this:
static void shuffleArray(int []array) {
int length = array.length;
for (int i = length -1; i > 0; i--) {
// generate a random 0 <= j < i
int j = (int)(Math.random() * i);
// swap elements at i and j
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
The approach proposed in most answers is extremely inefficient, as it works in O(N2) time. Think about it: at first you'll generate unused indexes with one attempt, but closer to the end, when almost all array is processed, it will require nearly N steps to generate next unused index.
The optimal O(N) approach is to create shuffled array of indexes (0..N) where each index appears only once and then process your original array in the order of shuffled indexes. Each step requires O(N) time, so the whole algorithm is O(N).
int[] input = new int[]{5, 4, 3, 6, 2, 1};
int []indices = new int[input.length];
//Fisher-Yates shuffle
Random rnd = new Random();
for (int i = 0; i < indices.length; i++) {
int j = rnd.nextInt(i + 1);
indices[i] = indices[j];
indices[j] = i;
}
for (int i : indices) {
System.out.println(input[i]);
}
I didn't use Collections.shuffle, as it would require usage of Collection and thus wrapped Integer elements, which is very inefficient comparing to the plain int array.
Also, if you are ok with modifying your original array, you can just shuffle it in place (using the same Fisher-Yates shuffle) and then consume it while traversing.
UPD: Replaced shuffling array of indices with shuffled initialization.
Since you have java 8, you can take advantage of the beautiful Stream API.
In short, you can do:
new Random().ints(1, 500).limit(500).forEach(p -> System.out.println(list[p]));
Where 1 is the lowest int generated (inclusive) and 500 is the highest (exclusive). limit means that your stream will have a length of 500, maybe in that argument you want to put list.length.
For your case:
int[] list = new int[] {1,2,3,4,5,6};
new Random().ints(0, list.length).limit(10).forEach(p -> System.out.println(list[p]));
Prints: 5 2 5 4 6 3 3 5 6 4 (Obviously will not print the same numbers for you)
Create a random integer that may be as high as the length of the array - 1. If the random integer is equal to a previous used random integer -- known by storing used integers in an array -- create a new random integer. Otherwise, print the string correlated with that index specified by the random integer. If the length of the array storing the used random integers is equal to the length of the array of strings, stop the process.
This should print all your strings only once each and randomly.
Here is the solution
public static void main(String[] args) {
int[] list = new int[] { 1, 2, 3 };
int[] aux = new int[list.length];
int countTimes = 0;
while (countTimes < list.length) {
int position = new Random().nextInt(list.length);
if (aux[position] != list[position]) {
System.out.println(list[position]);
aux[position] = list[position];
countTimes++;
}
}
}
As I said in the comments. This answer will work.. All you need to do is track the indices that it accessed so you don't repeat them or remove that element from the array.
void printRandom(int[] array) {
if (array.length == 0)
return;
Random rand = new Random();
int rnd = rand.nextInt(array.length);
int element = array[rnd];
array = ArrayUtils.removeElement(array, element);
System.out.print(element);
printRandom(array);
}
Just repeat this process until all elements are removed. Obviously add checks to prevent errors and keep in mind I haven't used JAVA in a long time so post back if you have issues!
Lastly keep in mind this deletes the array so you may want to wrap this code in a function and then copy the array as a local variable so you can reuse the original as needed
In this case we can print random value from array using like below :
Steps:
Create list object of Integer to hold printed indices
Get random number and check whether this index is already printed or not
if not printed then add it in list and print value from array using this index
if list size and array length is equal then terminate the loop
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class RandomIndices {
public static void main(String[] args) {
int[] list = new int[]{1, 2, 3};
Random random = new Random();
List<Integer> randomIndices = new ArrayList<>(); //to hold indices which are already printed
boolean isRemain = true;
while (isRemain) {
int randomIndex = random.nextInt(list.length);
if (!randomIndices.contains(randomIndex)) { //check random index value of array is printed or not
randomIndices.add(randomIndex);
System.out.println(list[randomIndex]);
}
if (randomIndices.size() == list.length) {
isRemain = false;
}
}}
}
Implement a simple "do while" statement to prevent duplicate numbers from showing up out of your array (I used a StringArray - but an IntegerArray would work the same way - as a side note, I can place the complete code up here but didn't want to do so if it didn't apply. I use a drop-down to select how many random words to generate - then display that set of true RANDOM words (non-repeated):
final Random rand1 = new Random();
final Random rand2 = new Random();
final int rndInt1 = rand1.nextInt(getResources().getStringArray(R.array.words).length);
int rndInt2 = rand2.nextInt(getResources().getStringArray(R.array.words).length);
if (rndInt1 == rndInt2){
do {
rndInt2 = rand2.nextInt(getResources().getStringArray(R.array.words).length);
}while (rndInt1 == rndInt2);//if indexes are equal - re-run the array search
}
outString = getResources().getStringArray(R.array.words)[rndInt1];
outString += ", " + getResources().getStringArray(R.array.words)[rndInt2];//concatenate the list
textWord = (TextView) findViewById(R.id.textWords);//An empty text field in my layout
textWord.setText(outString);//Set that empty text field to this string of random array elements
Related
import java.util.*;
public class Main {
public static void main(String[] args) {
// this section of code will require user input to have the value of n to be set
System.out.println(("What number would you like to set n equal to ?"));
Scanner sc = new Scanner(System.in);
System.out.print(("n= "));
int value = sc.nextInt();
System.out.println((""));
// this section of code set the two array only to hold the value of n
Random rand = new Random();
ArrayList<Integer> setA = new ArrayList<Integer>();
for (int i = 0; i < value; i++) {
int picks = rand.nextInt(1000);
setA.add(picks);
}
Collections.sort(setA);
System.out.println(setA);
ArrayList<Integer> setX = new ArrayList<Integer>();
for (int k = 0; k < value; k++) {
int picks = rand.nextInt(1000);
setX.add(picks);
}
Collections.sort(setX);
System.out.println(setX);
solution(setA,setX,value);
}
private static int solution(ArrayList<Integer> A1, ArrayList<Integer> X1, int value) {
// This section of code is where the arrays will be compared to find the nth smallest.
ArrayList<Integer> setF = new ArrayList<Integer>();
for (int c = 0; c < A1.size(); c++) {
for(int k = 0; k < X1.size(); k++) {
if(A1.get(c) < X1.get(k)) {
}
}
}
System.out.print(setF);
return value;
}
}
So far i have my program set up to have the user enter a number that will be used for the size of the array. Once the number has been entered the arrays are created with random numbers that will be place in order. Next I would like to go through each element of my arrays and compare to see which numbers can be placed in my Final array. In my final array is the nth smallest number which will be return. I can not merge the two array together.
For example if n = 10 below are my two arrays
A [124, 264, 349, 450, 487, 641, 676, 792, 845, 935]
B [2, 159, 241, 323, 372, 379, 383, 475, 646, 836]
124 < 2 this statement is false so 2 would get added to my final array list. Array B should move to the next element in the list.
124 < 159 this is true so 124 gets added to my final array list. Array A should move to the next element in the list.
264 < 159 this statement is false so 159.
Final Array [2,124, 159,...]
n smallest is 383.
Hopefully that example gives you an ideal of what I'm trying to accomplish.if you have something better let me know please..
Your solution would work but you can make your solution's time complexity o(n) rather than o(n^2).
What you could do is, since the arrays are equally sorted, you can compare both elements at position zero (like you're doing) and then whichever element is smaller, pop that element from the array and add it to the final array. Keep testing the zero(th) indexed element until one of the arrays is empty. Once its empty, you can just append the remaining other array on the end of the final array and that should achieve what you want.
So in some java code implementation:
private ArrayList<Integer> sortTwoArrays(ArrayList<Integer> arrayA, ArrayList<Integer> arrayB) {
ArrayList<Integer> finalArray = new ArrayList<>();
while(!arrayA.isEmpty() && !arrayB.isEmpty()) {
if (arrayA.get(0) < arrayB.get(0)) {
// remove element and store
finalArray.add(arrayA.remove(0));
}
else {
finalArray.add(arrayB.remove(0));
}
}
// Find out which array is not empty
// Adds remaining contents of non-empty array to end of finalArray
if (!arrayA.isEmpty()) {
finalArray.addAll(arrayA);
}
else if (!arrayB.isEmpty()) {
finalArray.addAll(arrayB);
}
return finalArray;
}
To get the nth smallest value, just add the value the user passes in as an argument to the function and then when you're returning the function, just return finalArray.get(nthIndex)
Example code showcase here.
Note: The original two ArrayLists will get destroyed from this method
If you want preserve the two arrays, I recommend keeping track of both indexes in the list inside variables and then incrementing based on when one item is less than another. Additionally, change the If statement check after the whie-loop from an isEmpty() check to a comparison like so indexOfArrayA == arrayA.size() - 1.
I hope this helps in anyway.
This question already has answers here:
Creating random numbers with no duplicates
(20 answers)
Closed 8 years ago.
Hello i have been working on insertion sort on set of numbers. i am able to add them to the array for performing the sorting but i was not able to generate unique values with large set of numbers to performing sorting(i:e)for 1000 values .is there any possibility i can generate unique random numbers for performing the sorting without adding values to the array?
public class InsertionBinary
{
public static void main(String Args [])
{
int[] nums = {1, 2, 3, 4, 5, 6, 7, 8, 24};
print(nums);
insertionsort(nums);
print(nums);
int loc = binarySearch(nums, 3);
System.out.println("2 is in position" + loc);
}
private static void swap(int[] list, int from, int to)
{
int temp = list[from];
list[from] = list[to];
list[to] = temp;
}
private static void print(int[] list)
{
for (int i = 0; i < list.length - 1; i++)
System.out.
print(list[i] + ", ");
System.out.println(list[list.length - 1]);
}
private static void insertionsort(int[] list)
{
int key;
int spot;
for (int pass = 1; pass < list.length; pass++)
{
key = list[pass];
for (spot = pass - 1; spot >= 0 && list[spot] > key; spot--)
list[spot + 1] = list[spot];
list[spot + 1] = key;
}
}
}
If all you want is a set of unique numbers for sorting, I would say the easiest approach would be to generate an array of size N containing the numbers 0 though N-1 (or 1 through N if you prefer) using a loop:
int size = 1000;
int[] nums = new int[size];
for(int i = 0; i < size; i++) {
nums[i] = i;
}
Then all you need to do is shuffle it, which you can do using your already-implemented swap() method and this helpful answer:
Random shuffling of an array
This has the advantage that it will run in O(n) time (instead of potentially infinite time if you're picking random numbers and then only inserting them if they're not already there).
Edit: You could also use Java's built-in shuffle method https://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#shuffle(java.util.List)
you can use Math.random() and also add one condition that will check, array contains that number or not, if not contains then add otherwise don't add.
One simple solution is using Set generate your random numbers and insert them in a Set, set wont allow duplicate numbers, something like this :
Random rnd= new Random();
Set<Integer> randomSet = new LinkedHashSet<Integer>();
while (randomSet.size() < 1000)
{
Integer randomNum = rnd.nextInt(max) + 1;
randomSet.add(randomNum);
}
but it may take infinite time to generate a set like this in theory, but its probability is very low.
Let's that I have a number N. N will be the size of the array.
int numArray [] = new numArray[N];
However, the contents of the array will hold every other number from 1 to positive N. This means that the entire size N array will not be full after that for loop. So after the for loop, I want to trim (or resize) the array so that there will no longer be any empty slots in the array.
Example :
Let's say N = 5;
That means, after the for loop, every other number from 1 to 5 will be in the array like so:
int arr[] = new int[N];
int arr[0]=1;
int arr[1]=3;
int arr[2]= null;
int arr[3]= null;
int arr[4]= null;
Now, I want to trim (or resize) after the for loop so that the indexes that hold null will be gone and then the array should be:
int arr[0]=1;
int arr[1]=3;
The size of the array is now 2.
You can't trim an array. The fastest approach is just to copy it into a smaller one, using System.arraycopy, which is almost always much faster than a for loop:
int somesize = 5;
int[] numArray = new int[somesize];
//code to populate every other int into the array.
int[] smallerArray = new int[somesize/2];
//copy array into smaller version
System.arraycopy(numArray, 0, smallerArray, 0, somesize / 2);
You can't change the size of an array in Java after it has been created.
What you can do however, is to create a new array of the size that you need.
Another important point is that you are creating an array of a primitive: int. Primitives are not objects and you cannot assign the value null to a primitive.
You need to create an array of java.lang.Integer if you want to be able to set entries in it to null.
Integer[] numArray = new Integer[N];
Thanks to a Java feature called auto-boxing, almost all code that works with primitive int values, also works with Integer values.
Steps:
Use Integer[] instead of int[]
Calculate the size that you need (count non-null entries in original array)
Allocate a new array of the size that you need
Loop over the old array, and copy every non-null value from it to the new array.
Code:
Integer[] oldArray = ...;
// Step 2
int count = 0;
for (Integer i : oldArray) {
if (i != null) {
count++;
}
}
// Step 3
Integer[] newArray = new Integer[count];
// Step 4
int index = 0;
for (Integer i : oldArray) {
if (i != null) {
newArray[index++] = i;
}
}
I think there is a bit shorter way to do the trimming itself.
Whats left is to find the proper index.
You can do:
int someIndex = Arrays.asList(arr).indexOf(null);
arr = Arrays.copyOfRange(arr,0,someIndex);
You surely better of with some more appropriate data structure, for example a list or a set depending on what's your intention with it later. That way you don't even need to create an N sized structure just so you'd have to reduce it anyway. Rather you create an empty list and add the elements that you actually need
import java.util.Arrays;
public static void main( String[] args )
{
int[] nums2 = {9,4,1,8,4};
nums2 =Arrays.copyOf(nums2,3);
for (int i : nums2) {
System.out.print(i+" ");
}
}
//Output
9 4 1
What Im trying to do is take my array coins[]. And basically rearrange each coin to a different position. This is what i have so far. When I do this though, nothing happens. Meaning all the values stay the same. Except for the last one. That one changes.
public void shake()
{
for (int i = 0; i < coins.length; i++)
{
int index = Coin.RANDOM.nextInt(coins.length);
Coin temp = coins[index];
coins[index] = coins[i];
coins[i] = temp;
System.out.print(coins[i] + ", ");
}
}
I instantiate random like this:
public static long SEED = System.currentTimeMillis();
public static Random RANDOM = new Random(SEED);
Please notice that this line
System.out.print(coins[swap] + ", ");
displays the already moved (swapped) coin. Maybe you were thinking about displaying the new coin at i index: coins[i] (which wouldn't be correct anyway, as the already displayed coin still can be swapped in the next iterations). Probably it's better to create a second for loop to display final coin values.
But this isn't only problem here. To randomly shuffle an array you should use Fisher-Yates algorithm which is slightly different than your method. You can find Java implementation of this algorithm on SO.
If you had a List<Coin> instead of Coin[] (list instead of array) you could use the Collections.shuffle method and be sure that the algorithm is correct and you'll always get random result.
As you are using swap as index with which you will be swapping the current value you can edit your Random number generator to generate random numbers between certain range (say 0 - coins.length) and then you can change your implementation to something like this
public void shake()
{
Coin temp;
for (int i = 0; i < coins.length; i++)
{
//int swap = Coin.RANDOM.nextInt(coins.length);
temp = coins[swap];
coins[swap] = coins[i];
coins[i] = temp;
System.out.print(coins[i] + ", ");
}
}
For the commented line in your code check THIS to update your random number generator to generate numbers between two values. Then each time you generate swap(index) between i+1 - coins.length and continue this till you fully exhaust the array. This ensures that you don't make a swap at the index the value for which you have already displayed. But I am not completely confident that this would indeed be a random shuffle as in the beginning of the loop you have more choices for the swap index then you would have sometime later in the loop and the shake is not completely random. This solution is only in case you want to strictly implement your own shake method without using the Collections.shuffle as #Tomek mentioned.
why don't you using Collections? its so simple to assign random indexes to each value in array or ArrayList.
Collections.shuffle(coins);//if coins is array
Collections.shuffle(Arrays.asList(coins));//if coins is an ArrayList
You might use Knuth's shuffling algorithm which rearranges the array so that a result is a uniformly random permutation. Algorithm is simple but works like a charm:
Iterate over array and in iteration i pick random integer swap between 0 and i
Swap array[i] and array[swap]
Note that in your implementation random is generated between 0 and 11, which doesn't seem to produce good shuffling.
Here is a code example with shuffling for array of integers:
import java.util.Random;
public class Test {
public static long SEED = System.currentTimeMillis();
public static Random RANDOM = new Random(SEED);
public static void shuffle(int[] numbers)
{
for (int i = 0; i < numbers.length; i++)
{
int swap = RANDOM.nextInt(i + 1);
int temp = numbers[swap];
numbers[swap] = numbers[i];
numbers[i] = temp;
}
for (int i = 0; i < numbers.length; i++) {
System.out.print(numbers[i] + ", ");
}
}
public static void main(String[] args) {
shuffle(new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11});
}
}
Output for test run is:
5, 11, 6, 1, 3, 10, 9, 2, 4, 7, 8,
Use this method and pass your array in parameter
Collections.shuffle(arrayList);
This method return void so it will not give you a new list but as we know that array is passed as a reference type in Java so it will shuffle your array and save shuffled values in it. That's why you don't need any return type.
You can now use arraylist which is shuffled.
Sourse: https://stackoverflow.com/a/16112539/4291272
This question already has answers here:
Random shuffling of an array
(31 answers)
Closed 6 years ago.
how to print an array in random order in java?
example:
int[] myArray = {5,4,3,2,1};
when printed, result should possibly be:
3 2 1 4 5
or
4 3 2 5 1
You should look at writing a Fisher-Yates shuffle. It's pretty easy to do, and efficient. Effectively you logically partition the array into a "shuffled" part and an "unshuffled part" - then repeatedly pick a random element from the unshuffled part and swap it with the first element from the unshuffled part, to make that part of the shuffled part.
Alternatively, create a List<Integer> instead and then use Collections.shuffle. It's unfortunate that there isn't an equivalent for arrays, but Java's type system doesn't do terribly well in terms of making either arrays or primitives generic :(
(I'm assuming you know how to do the printing side, and that it's the shuffling side which is the tricky bit for you.)
Create a new array order = {0, 1, 2, 3, 4} and shuffle it. Then something like
for (int i: order)
System.out.print(myArray[i]);
Swap between random elements of array:
import java.util.Random;
public class JavaTest {
public static void main(String[] args) {
int[] myArray = {5,4,3,2,1};
Random random = new Random();
for (int i=0; i<20; i++) { // 20: is custom number
int i1 = random.nextInt(myArray.length);
int i2 = random.nextInt(myArray.length);
int tmp = myArray[i1];
myArray[i1] = myArray[i2];
myArray[i2] = tmp;
}
for (int i=0; i<myArray.length; i++)
System.out.print(myArray[i]);
}
}
create an instance of the random class and then use the integer i which will be the index. where it lands, compute before element and after element length and then do the same recursively.
int main(){
int array[10]={1,2,3,4,5,6,7,8,9,10};
int i,k,temp;
struct timespec spec;
long ms; // Milliseconds
/* pick a random number from 0 to 9 elements */
for (i = 9;i>0;i--){
clock_gettime(CLOCK_REALTIME, &spec);
ms = spec.tv_nsec / 1.0e6;
srand((int )ms);
temp = rand();
temp = temp % i;
printf(" %d \t ",array[temp]);
k = array[i];
array[i] = array[temp];
array[temp] = k;
}
printf(" %d \t \n ",array[0]);
return 0;
}