I need to initialize an array of characters with 1000 random characters between [a,..z] and [A,..,Z].
I don’t want do this by first generating only characters between [a,..z] and then only characters in [A...Z] but treat all 52 characters equally.
I know one way to do this is to generate a random number between 0 and 51 and assign it one of the character values.
How would I approach this problem or assign values to the random numbers between 0 and 51?
You have got the interesting code idea.
Here might be the thought.
Take all the a-z and A-Z and store them in an array[].
Randomly generate a number between 1-52 (use API classes for that).
You will get a number in step 2, take it as an array index and pick this index from array[] of chars.
Place that picked char to your desired location/format............
Process it.
Best Regards.
Let me give you some general guidelines. The "one way to do this" you mentioned works. I recommend using a HashMap<E>. You can read more about hashmaps in the docs:
http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
Alternatively, you can use another array that contains a - z and A - Z and you can use the index number to refer to them. But in this case I think it makes more sense to use a HashMap<E>.
I think you know how to create a Random object. But if you don't, check out the docs:
http://docs.oracle.com/javase/7/docs/api/java/util/Random.html
So you basically use the nextInt method of the Random class to generate a random number. And you can put that random number into your HashMap or array. And then you just put that character you get into an array that stores the result of the program.
This is the sample work, hope this will work for you
import java.util.ArrayList;
import java.util.Random;
public class RandomNumber {
public static void main(String args[]) {
char c;
ArrayList<Character> character = new ArrayList<Character>();
Random rn = new Random();
for (int i = 0; i < 500; ++i) {
character.add((char) (rn.nextInt(26) + 66));
character.add((char) (rn.nextInt(26) + 97));
}
System.out.println(character);
}
}
The simplest approach would be:
// constant declared in the class
static final int LETTERS_COUNT = 'z'-'a'+1;
char[] randomChars = new char[500];
Random r = new Random();
for(int i=0; i<randomChars.length; i++) {
randomChars[i] = (char)(r.nextInt(LETTERS_COUNT) + (r.nextBoolean() ? 'a' : 'A'));
}
If you don't like accessing random number generator two times, you can generate numbers from 0 to 51:
for(int i=0; i<randomChars.length; i++) {
int num = r.nextInt(LETTERS_COUNT*2);
randomChars[i] = (char)(num >= LETTERS_COUNT ? 'a'+(num-LETTERS_COUNT) : 'A'+num);
}
However I don't see any advantages of this approach. Internally r.nextInt may also change its internal state several times. The distribution should be similar in both cases.
You can this with a function using either arrays or arithemtic.
Note that you can calculate with characters like with numbers, because they are stored as numbers (http://www.asciitable.com/), you will also note that digits, small letters and big letters are stored in sequence so that accessing ranges is pretty easy with a simple for-loop.
private Random r = new Random();
public char randomLetter() {
int randomNumber = this.r.nextInt(52);
if(randomNumber >= 26) {
return (char)(('A'+randomNumber)-26);
} else {
return (char)('a'+randomNumber);
}
}
The version using an array will be faster, but can only be used if the set of possible outcomes is small enough to be stored.
private Random r = new Random();
private static char[] set = new char[52]; //static because we only need 1 overall
static { //this is a static "constructor"
for(int i = 0; i < 26; i++) {
set[i] = (char)('a'+i);
set[i+26] = (char)('A'+i);
}
}
public char fastRandomLetter() {
final int randomNumber = this.r.nextInt(52);
return set[randomNumber];
}
public class ShuffleArray {
public static void main(String[] args) {
int[] array = { 1, 2, 3, 4, 5, 6, 7 };
Random rand = new Random();
for (int i = 0; i < array.length; i++) {
int randomIndexToSwap = rand.nextInt(array.length);
int temp = array[randomIndexToSwap];
array[randomIndexToSwap] = array[i];
array[i] = temp;
}
System.out.println(Arrays.toString(array));
}
}
Related
This question already has answers here:
Creating random numbers with no duplicates
(20 answers)
best way to pick a random subset from a collection?
(10 answers)
Closed 7 years ago.
I am trying to get this code to run without duplicates but am having no success researching this area.
Its the start of a question I am doing which will ask the user to input the missing element. However, when I generate random elements I am getting duplicates
import java.util.Random;
public class QuestionOneA2 {
public static void main(String[] args) {
String[] fruit = {"orange", "apple", "pear", "bannana", "strawberry", "mango"};
Random numberGenerator = new Random();
for (int i = 0; i < 5; i++) {
int nextRandom = numberGenerator.nextInt(6);
System.out.println(fruit[nextRandom]);
}
}
}
There are many different approaches you can consider, depending on how flexible the algorithm should be.
Taking 5 random elements from a list of 6, is the same as selection 1 element from the list of 6 that you don't choose. This is a very inflexible, but very easy.
Another approach could be to delete the element from the list, and decrease the maximum random number. In this cause I would advice to not use a String[].
When you generate a random number, I suggest adding it into an array.
Then, when you generate your next number, do some sort of search (google for something efficient) to check if that number is already in the array and thus, has been used already.
If it is, generate a new one, if its not, use it.
You can do this by nesting it in a while loop.
Although, from what I can tell from your question, you would be better off just creating a copy of your fruit array using an ArrayList and then, when you generate a random number to select a fruit, simply remove this fruit from this new list and decrement the range of random numbers you are generating.
You can use a Set to validate if the random generated number is duplicate or not. You just have to keep generating randomNumber until you find a unique random and then add it to the Set to prevent the duplicates.
Here is a quick code snippet:
public static void main(String[] args) {
String[] fruit = {"orange", "apple", "pear", "bannana", "strawberry", "mango"};
Random numberGenerator = new Random();
/* Generate A Random Number */
int nextRandom = numberGenerator.nextInt(6);
Set<Integer> validate = new HashSet<>();
/* Add First Randomly Genrated Number To Set */
validate.add(nextRandom);
for (int i = 0; i < 5; i++) {
/* Generate Randoms Till You Find A Unique Random Number */
while(validate.contains(nextRandom)) {
nextRandom = numberGenerator.nextInt(6);
}
/* Add Newly Found Random Number To Validate */
validate.add(nextRandom);
System.out.println(fruit[nextRandom]);
}
}
Output:
mango
apple
strawberry
pear
orange
You can wrap int into 'Interger' and add it to Set. Set holds no duplicates so there will be only unique values in it. So then just check if a Set already has given Integer with Set.contains(Integer).
my personal solution :
private static int[] randomIndexes(int len) {
int[] indexes = new int[len];
for (int i = 0; i < len; i++) {
indexes[i] = i;
}
for (int i = len - 1, j, t; i > 0; i--) {
j = RANDOM.nextInt(i);
t = indexes[j];
indexes[j] = indexes[i];
indexes[i] = t;
}
return indexes;
}
See it in action : https://gist.github.com/GautierLevert/a6881cff798e5f53b3fb
If I understand you correctly, then you want to choose n-1 elements at random from a list of n elements. If yes, then I recommend to choose just one at random and take all the others.
Arrays.shuffle(fruit);
int notThis = numberGenerator.nextInt(6);
for(int i = 0; i < fruit.length; i++)
if(i!=notThis) System.out.println(fruit[i]);
Copy your array into List<String>, then shuffle it, then just pick elements one by one:
List<String> copy = new ArrayList<>(Arrays.asList(fruit));
Collections.shuffle(copy);
for (String f : copy)
System.out.println(f);
I think it will be easier using an ArrayList, and also controlling the generation of the random number as shown below.
import java.util.Random;
public class QuestionOneA2 {
public static void main(String[] args) {
List<String> fruits = new ArrayList<>();
fruits.add("orange");
fruits.add("apple");
fruits.add("pear");
fruits.add("bannana");
fruits.add("strawberry");
fruits.add("mango");
Random numberGenerator = new Random();
int nextRandom;
for (int i = 0; i < 6 ; i++) {
nextRandom = numberGenerator.nextInt(6 - i);
System.out.println(fruits.get(nextRandom));
fruits.remove(nextRandom);
}
}
}
fruit.remove(fruit[nextRandom]);
Maybe, is it the remove sub-method?
package selectionsortintro;
public class SelectionSortIntro {
public static void main(String[] args) {
int nums[] = { 22, 30, 15, 1, 7, 87, 65, 24, 22, 0 };
// print out unsorted list
for (int count = 0; count < nums.length; count++) {
System.out.print(nums[count] + " ");
}
System.out.println("\n---------------------------------");
selectionSort(nums);
// print out sorted list
System.out.println("After sorting using the Selection Sort," + " the array is:");
for (int count = 0; count < nums.length; count++) {
System.out.print(nums[count] + " ");
}
}
public static void selectionSort(int data[]) {
int smallest;
for (int i = 0; i < data.length - 1; i++) {
smallest = i;
// see if there is a smaller number further in the array
for (int index = i + 1; index < data.length; index++) {
if (data[index] < data[smallest]) {
swap(data, smallest, index);
}
}
}
}
public static void swap(int array2[], int first, int second) {
int hold = array2[first];
array2[first] = array2[second];
array2[second] = hold;
}
}
I want to add a random amount of random integers into the array, so the selection sort algorithm will sort them out. The only problem is, I don't know how to store the array with random numbers and not be a fixed amount. If that's confusing, when you make the array it's like :
int[] randomNumbers = new int[20];
Where 20 is the amount of numbers generated. Well I want to have the user be the judge of how many numbers are randomly generated into the array. So I'm thinking maybe use ArrayList? But then, I get confused as to how I can use it to add the random numbers into itself. If anyone can help me that'd be awesome
EDIT: So I got input using scanner, but I really would prefer JOptionPane as the input dialog looks a lot nicer, but if scanner is the only way that's fine. So now that that's done, I just need to actually FILL the array with random integers, does anyone know how to do that?
Here's what I came up with, I get an error with my code, if anyone could help that'd be awesome.
Scanner input = new Scanner(System.in);
Scanner s = new Scanner(System.in);
System.out.println("enter number of elements");
int n = s.nextInt();
int nums[]=new int[n];
Random randomGenerator = new Random();
//print out unsorted list
for (int count = 0; count < nums.length; count++) {
System.out.print(nums[count] + " ");
nums[n] = randomGenerator.nextInt(1001);
}
Here's an example using a traditional array and a JOptionPane:
import javax.swing.*;
import java.util.Random;
public class Random_int_array {
public static void main(String[] args) {
JFrame frame = new JFrame("Total number of integers");
int iTotalCount = Integer.parseInt(JOptionPane.showInputDialog(frame, "What is the total number of integers?"));
int[] array = new int[iTotalCount];
Random randomGenerator = new Random();
for(int i=0; i < iTotalCount; i++){
array[i] = randomGenerator.nextInt(1001);
}
// Now you can do whatever processing you would like to do
// For the sake of this answer, I will just print the numbers
for(int i=0; i < array.length; i++){
System.out.println(array[i]);
}
// We should explicitly call exit because we used a form/window
System.exit(0);
}
}
And here's an example of using an ArrayList with JOptionPane instead of a regular int[] array;
import javax.swing.*;
import java.util.Random;
import java.util.ArrayList;
public class Random_int_array {
public static void main(String[] args) {
JFrame frame = new JFrame("Total number of integers");
int iTotalCount = Integer.parseInt(JOptionPane.showInputDialog(frame, "What is the total number of integers?"));
// Can also be written as: ArrayList<Integer> array = new ArrayList<>();
// in newer versions of Java.
ArrayList<Integer> array = new ArrayList<Integer>();
Random randomGenerator = new Random();
for(int i=0; i < iTotalCount; i++){
array.add(randomGenerator.nextInt(1001));
}
// Now you can do whatever processing you would like to do
// For the sake of this answer, I will just print the numbers
for(int i=0; i < array.size(); i++){
System.out.println(array.get(i));
}
// We should explicitly call exit because we used a form/window
System.exit(0);
}
}
Note: ArrayLists cannot use primitive data types, so you must specify it as using an Integer rather than an int.
Adding an option to set the size of the array based off of user input is a bit more tricky
The easiest way to code it is to pass in command line arguments and read them in your args variable in your main method
Another way to read input is the Scanner class
Whichever way you choose, you may end up with a String variable you need to convert to an int with
String input = args[0]; //or use Scanner
int size = Integer.parseInt(input);
Three different methods of generating random integers, from easiest to implement to hardest
To generate a random int [0, max)
(int)(Math.random() * max)
or use
Random r = new Random();
r.nextInt(max);
A more complicated way to generate a more random number instead of Java's pseudo-random generators would be to query random.org for data. Do note that this may take a bit longer to set up and code, as well as relying on third party servers (no matter how reliable they may be)
You can use the random int to initialize the input array with a random length, then fill in the values with random numbers with a for loop
I want to generate 6 different random numbers by using Math.random and store them into an array.
How can I make sure that they are different? I know I need to use for-loop to check the array but how...
This is the range. I only need numbers between 1 and 49.
( 1 + (int) (Math.random() * 49) )
In Java 8:
final int[] ints = new Random().ints(1, 50).distinct().limit(6).toArray();
In Java 7:
public static void main(final String[] args) throws Exception {
final Random random = new Random();
final Set<Integer> intSet = new HashSet<>();
while (intSet.size() < 6) {
intSet.add(random.nextInt(49) + 1);
}
final int[] ints = new int[intSet.size()];
final Iterator<Integer> iter = intSet.iterator();
for (int i = 0; iter.hasNext(); ++i) {
ints[i] = iter.next();
}
System.out.println(Arrays.toString(ints));
}
Just a little messier. Not helped by the fact that it's pretty tedious to unbox the Set<Integer> into an int[].
It should be noted that this solution should be fine of the number of required values is significantly smaller than the range. As 1..49 is quite a lot larger than 6 you're fine. Otherwise performance rapidly degrades.
Create a list containing the numbers 1 to 49.
Create a random number x between 0 and the size of the list, take the number being at index x in the list, and remove it from the list.
Repeat the previous step 5 times. And you're done. Note that java.util.Random has a nextInt(int max) method that you should use instead of Math.random().
Note regarding performance: this solution has an advantage compared to the "try until you get 6 different numbers" various solutions: it runs in a O(n) time. It doesn't matter much for 6 unique numbers out of 50, but if you want to get 48 or 49 unique random numbers out of 50, you'll start seeing a difference, because you might have to generate many random numbers before getting one that isn't already in the set.
EDIT:
to reduce the cost induced by the removal of the elements in the list, you could instead simply replace the element at index x with the last element of the list (and at the second iteration, with the element at size - 2, etc.)
You can use a Set.
Set<Integer> s = new HashSet<>();
while(s.size() != 6){
s.add(1 + (int) (Math.random() * 49));
}
Integer[] arr = s.toArray(new Integer[s.size()]);
This is enough to do this in your case because the number of distinct random numbers is relatively small compared to the size of the range you generate them.
Otherwise I would go with #JBNizet approach.
Generate any 6 numbers (not necessarily different). Order them.
a1 <= a2 <= a3 <= a4 <= a5 <= a6
Now take these 6 numbers
a1 < a2 + 1 < a3 + 2 < a4 + 3 < a5 + 4 < a6 + 5
These 6 are different and random.
The idea of this construct comes from some combinatorial proofs.
Its advantage is that it's simple, fast, and deterministic.
I think the time complexity is O(count*log(count)).
I wonder if it can be improved.
import java.util.TreeMap;
public class Test005 {
public static void main(String[] args) {
int count = 6;
int min = 1;
int max = 49;
// random number mapped to the count of its occurrences
TreeMap<Integer, Integer> mp = new TreeMap<Integer, Integer>();
for (int i=0; i<count; i++){
int d = ( min + (int) (Math.random() * (max-count+1)) );
if (!mp.containsKey(d)){
mp.put(d, 0);
}
mp.put(d, mp.get(d) + 1);
}
// now ensure the output numbers are different
int j = 0;
for (int num : mp.keySet()){
int cnt = mp.get(num);
for (int i=0; i<cnt; i++){
System.out.println(num + j);
j++;
}
}
}
}
I've just came up with a small idea for Java 8-.
Set<Integer> set = new LinkedHashSet<>();
while(set.size() != 6)
set.add(rnd.nextInt(49) + 1);
Instead of checking that the array has no duplicates, you can use a bit more smartness while generating the numbers, such that uniqueness is enforced at the outset.
Create a boolean[] as long as your range (49 entries);
generate a random number from the full range;
put that number into your output array;
"cross out" the corresponding index in the boolean[];
now generate another random number, but curtail the range by one (now 48);
instead of directly using that number as output, scan your boolean[], counting all the non-crossed entries. Stop when you reach the count equal to the random number generated in step 5. The number corresponding to that entry is your output number;
go to step 4.
in your case n=6
public static int[] chooseAny(int n){
int[] lottery = new int[n];
int[] chooseFrom = new int[49];
for(int i=1 ; i <= 49 ; i++)
chooseFrom[i-1] = i;
Random rand = new Random();
int N = 49;
int index;
for(int i=0 ; i < n ; i++){
//pick random index
index = rand.nextInt(N);
lottery[i] = chooseFrom[index];
chooseFrom[index] = chooseFrom[N-1];
N--;
}
return lottery;
}
Just keep generating numbers and adding them to the array as long as they are unique; psuedocode:
num = genNextRand()
For (array length)
If (num not in array)
addToArray()
Repeat while length not equal 6
Create a variable last; initialize it to 0.
Next, in a loop x from 0 to 5, create a random number between last+1 and 49-6+x. Store this number in a list, and set last to the number generated this way.
You will end up with an ordered list of 6 random numbers in the range of 1..49 with no repeats.
That code generate numbers from 6 to 0 and save in ArrayList.
If generated number was duplicated the program generate numbers again.
If generated number is different that number is added.
Code:
private ArrayList<Integer> arraylist = new ArrayList<Integer>();
private Random rand = new Random();
public void insertNumber() {
while (true) {
int i = generateNumber();
if(!isGenerateNumberExists(i)){
addNumber(i);
break;
}
}
}
//Generate numbers
private int generateNumber() {
return rand.nextInt(6);
}
//Confirm if that number exists
private boolean isGenerateNumberExists(int y) {
for (int num : arraylist) {
if (num == y) {
return true;
}
}
return false;
}
//Add number to arrayList
private void addNumber(int x) {
arraylist.add(x);
}
The following code shows 4 int variables:
int xy1 = 724329;
int xy2 = 714385;
int xy3 = 715440;
int xy4 = 696492;
I'm pretending to code an app that, by opening it, shows one of those numbers (NOT numbers between them) on java console, randomly. I know that Math.Random class can be used to solve these kind of issues, but I don't know what is the proper way to do so.
So, thanks.
Well it sounds like you just want a collection of possible values, and an index between 0 and 3 inclusive:
int[] values = { 724329, 714385, 715440, 696492 };
Random random = new Random(); // Ideally initialize once for the entire app
int index = random.nextInt(4);
int value = values[index];
Place them into an array and use Random to select a number between 0-3 and use it as a key to select the value from the array.
Try this one.
This line
r.nextInt(nums.length)
selects an integer from 0 to nums.length-1.
Then I print out the randomly selected number from the nums array.
I repeat this 20 times just for demonstration purposes.
import java.util.Random;
public class Test015 {
public static void main(String[] args) {
int[] nums = {724329, 714385, 715440, 696492};
Random r = new Random();
for (int i=0; i<20; i++){
int index = r.nextInt(nums.length);
System.out.println("Number randomly chosen: " + nums[index]);
}
}
}
This question already has answers here:
Non repeating random numbers
(2 answers)
Closed 8 years ago.
When using the random utility in java, you get some numbers like this: 1271, 34556, 177, etc... What is the simplest way to make it so the digits don't repeat?
You could shuffle the array [1,2,3,4,5,6,7,8,9] and read that as a number.
If you don't want to fix the number of digits, or allow a non-leading zero, it gets more complicated (if you care about some sort of equal distribution).
You could initialize a List with the digits 0-9. Then randomize this list and poll a random amount of elements (between 1 and 9) from this list. Concatenate the digits and you have your number with non-repeating digits.
How about creating a loop that checks if the generated random number meets your requirements.
final Random rnd = new Random();
int n;
do {
n = rnd.nextInt(1000);
} while(containsRepeatingDigits(n));
containsRepeatingDigits can look like this:
boolean containsRepeatingDigits(final int n) {
final boolean digits[] = new boolean[10];
for(char c : String.valueOf(n).toCharArray()) {
final int i = c-'0';
if(digits[i])
return true;
digits[i] = true;
}
return false;
}
You could check if the random number has repeating digits and generate a new one if it does. It's written in C#, but you should be able to convert this to Java real easy.
private static Random rand = new Random();
public static int GenerateNumberNonRepeat()
{
int number;
do
{
number = rand.Next();
} while (IsRepeating(number));
return number;
}
public static bool IsRepeating(int number)
{
string textual = number.ToString();
for (int i = 0; i < textual.Length; i++)
{
for (int j = i + 1; j < textual.Length; j++)
{
if (textual[i] == textual[j])
return true;
}
}
return false;
}
Another way to generate those numbers is to generate arbitrary number, and in case that it contains repeating digits either generate a new one, or remove the repeating digits (by e.g. increment the number until there are no more repeating numbers).
In contrast to proposed shuffle/select approach this has the advantage, that you keep (more or less) the distribution of the original rng.
This code may help you
Set set = new HashSet<Integer>();
Random rand= new Random();
public int getNonRepeatingRandomNumber() {
int intV = rand.nextInt();
if(set.contains(intV)) {
return getNonRepeatingRandomNumber();
}
else {
set.add(intV);
return intV;
}
}