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;
}
Related
I got the 2d array to print but with all zero's and the only random number comes up on the bottom right corner
How do I get the code to print random numbers in all the elements of the 2d array?
Here is my code:
public static void main(String[] args) {
int columns = 8;
int rows = 4;
int rLow = 2;
int rHigh = 9;
printRandos(columns, rows, rLow, rHigh);
}
public static void printRandos(int clmn, int rws, int rlow, int rhigh) {
Random rando = new Random();
int randoNum = rlow + rando.nextInt(rhigh);
int[][] randoArray = new int[rws][clmn];
for (int i = 0; i < rws; i++) {
for (int k = 0; k < clmn; k++) {
randoArray[rws - 1][clmn - 1] = randoNum;
System.out.print(randoArray[i][k] + " ");
}
System.out.print("\n");
}
}
for (int i = 0; i < rws; i++)
{
for (int k = 0; k < clmn; k++)
{
int randoNum = rlow + rando.nextInt(rhigh);
randoArray[i][k] = randoNum;
System.out.print(randoArray[i][k]+" ");
}
System.out.print("\n");
}
your mistake inside the inner for loop of the printRandos method. Firstly your random number is outside the loop so your array elements were receiving the same number all the time. Another mistake is that you are assigning the value to the same array element all the time i.e rws-1 and clmn-1 .
inside your inner loop replace it with this:
int randoNum = rlow + rando.nextInt(rhigh);
randoArray[i][k] = randoNum;
System.out.print(randoArray[i][k]+" ");
Your bug is in this line:
randoArray[rws-1][clmn-1] = randoNum;
This stores your random number into randoArray[rws-1][clmn-1] each time, which as you noticed, is the bottom right corner. rws is always 4, and clmn is always 8. So you store the same number there 32 times, which gives the same result as storing it only once.
In the following line you are correctly printing the number from the current array location:
System.out.print(randoArray[i][k]+" ");
An int array comes initialized with all zeroes, and since except for the last corner you have not filled anything into your array, 0 is printed.
Also if you want different random numbers in all the cells, you would need to call rando.nextInt() inside your innermost for loop.
Unless you need this 2-D array for some purpose (which doesn't show from the minimal example code that you have posted), you do not need it for printing a matrix of random numbers, i.e., you may just print the numbers form within your loop without putting them into the array first.
Finally if rhigh should be the highest possible random number in the array, you should use rando.nextInt(rhigh - rlow + 1). With rlow equal to 2 and rhigh equal to 9 this will give numbers in the range from 0 inclusive to 9 - 2 + 1 = 8 exclusive, which means that after adding to rlow = 2 you will get a number in the range from 2 to 10 exclusive, in other words, to 9 inclusive.
I am on purpose leaving to yourself to fix your code based on my comments. I believe your learning will benefit more from working it out yourself.
Your assign the array value outside the array length
int[][] randoArray = new int[rws][clmn];
randoArray[rws][clmn] = randoNum;
Here randoArray[rws] is out of bounds.
This question already has answers here:
Java Array of unique randomly generated integers
(10 answers)
Closed 5 years ago.
i want to create an array of 10000 unique random elements. Till now i only figure out how to create random integers and fill an array and finding the doubles and deleted them. But this decrease the size of the array which i dont want it.
So the question is how i can fill an array with unique integers as elements without decreasing the size of the array.
You could use this code. Usage of Set will eliminate duplicates and you are fetching random numbers until you get 10000 different random integers.
Set<Integer> numbers = new HashSet<>();
Random r = new Random();
while (numbers.size() < 10000) {
numbers.add(r.nextInt(100000));
}
Integer[] a = new Integer[numbers.size()];
a = numbers.toArray(a);
I found this great solution:
This solution doesn't need any Collection class.
public static int[] createRandomNumbers(int howMany) {
int n = howMany + 1;
int a[] = new int[n];
for (int i = 0; i < n; i++) {
a[i] = i;
}
int [] result = new int[n];
int x = n;
SecureRandom rd = new SecureRandom();
for (int i = 0; i < n; i++) {
int k = rd.nextInt(x);
result[i] = a[k];
a[k] = a[x-1];
x--;
}
return result;
}
System.out.println(Arrays.toString(createRandomNumbers(10000)));
Reference: Best way to create a list of unique random numbers in Java
Hope it helps
Try this logic:
USE AN ARRAYLIST ENTIRELY, THEN CONVERT TO AN ARRAY AT THE END OF THE ENTIRE OPERATION.
Declare an arraylist
For every random number generated, check if the number already exists in the arraylist (using the .contains() method). If it does, repeat the process, else, move to the next number.
Code example:
Arraylist<Integer> arr = new Arraylist<>();
arr.add(generate()); //I included this line so that the arraylist won't be empty
//Note that the method *generate()* generates a new random number
for(int i = 0; i < 9999; i++){
int next = generate(); //the method that generates your number
if(arr.contains(next)){
i--; //The entire operation will be repeated for this index.
}
else{
arr.add(next); //Add the number to the arraylist
}
}
int[] finalArray = arr.toArray(); //Your final resultant array!
I hope this helps.. Merry coding!
You can use Set. This Collection that contains no duplicate elements.
Documentation https://docs.oracle.com/javase/7/docs/api/java/util/Set.html
Set<Integer> numbers = new HashSet();
do {
numbers.add(ThreadLocalRandom.current().nextInt());
} while(numbers.size() < 10000);
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
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.
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