Im a bit confused on how to do this particular process in Java.
I have to use a RNG to print a specific amount of values to an array, but the part I can't figure out is how to give each array element a value that is to be incremented if the RNG gives that value. Example:
Array
0
1
2
If the RNG returns a 2, then increment the 2 in the array, and then display it like this
0
1
2 1 (as in, it rolled a 2 once so its now 1)
I have no problems doing the user input and RNG part, but I don't know how to display it like that
Any help would be appreciated, thanks.
Code so far
public static void main(String[] args) {
Scanner input = new Scanner( System.in); //Declares the scanner
Random randomNumbers = new Random(); // Declares the random property you will need later
//Variables
int randomrequest = 0; //Declares randomnum as a integer with a value of 0, this is what the user inputs as the number they want.
int randomrange = 0; //Declares the number for the number range for the random number generator
int randomcounter = 0;//Declares the counter you will need later as 0
int result = 0; //This variable is for the random number generation result
System.out.printf( "How many random numbers do you want to generate?" ); //asks for the number to generate
randomrequest = input.nextInt(); //Makes the user enter a value to and then stores it in this variable.
System.out.printf( "What is the number of values for each random draw?" ); //asks for the number range
randomrange = input.nextInt(); //See above
//Ok now we have to use the inputed information to do the rest of the processing before we can display it
//First, create the array and give it the size equal to the number range entered
int[] array = new int[ randomrange ]; // Declares the array with the amount of slots for each outcome
//We need to use a loop here to make sure it rolls the RNG enough times
while (randomcounter != randomrequest) { //This tells it generate a random number until the counter equals the entered amount.
result = randomNumbers.nextInt( randomrange ); //Generates a random number within the range given
randomcounter += 1; //increments the counter, so that it will eventually equal the entered number, and stop.
}//End of do while
}//end of Public static void
}//End of entire class
The following code should work for your solution:
while (randomcounter != randomrequest) {
result = randomNumbers.nextInt(randomrange);
array[result] += 1;
randomcounter +=1;
for (int i = 0; i < array.length; i++)
{
system.out.print(array[i] + " ");
}
system.out.println();
}
If I'm interpreting your question correctly, one thing you can try is to have each element in the array be a counter for its index. So if your random number generator produces a 2, you increment the value in array[2].
A concise way to put it might be:
while (randomCounter++ != randomRequest) {
array[randomNumbers.nextInt(randomRange)]++;
}
Related
So far, i am using .charAt() to discern the first and 3rd characters in say "1d6", meaning roll a six sided die once. To do this i have made a for loop to use the random class with a range of 1 and the die type (in this case 6), and the loop is supposed to execute it a number of times determined by the input (in this case, 1). Problem is the values im getting are rather random.
import java.util.Scanner;
import java.util.Random;
public class DiceRoller3 {
public static void main(String[] args) {
//Creates a new scanner object
Scanner input = new Scanner(System.in);
//Creates a new Random object
Random random = new Random();
//fluff text
//System.out.println("What would you like to roll?");
//Sets dieInput equal to the input the scanner reads.
String dieInput = input.next();
//sets noOfDice equal the the first character of the dieInput String
int noOfDice = dieInput.charAt(0);
//sets dieType equal to the 3rd character of the dieInput String
int dieType = dieInput.charAt(2);
//test to show the value of noOfDice and dieType
System.out.println(dieInput);
System.out.println(noOfDice);
System.out.println(dieType);
//Loop to roll the die type determined by the input, a number of times
that is also determined by the input
for(int x = 1; x <= noOfDice; x++)
{
int roll = random.nextInt(dieType) + 1;
System.out.println(roll);
}
}
}
When i run this, the the program tells me that the value of noOfDice and dieType are equal to 49 or 50 or some other large number which i'm not understanding why that is the case. the value of dieInput is correct, but when the two characters are read from dieInput they become incorrect. any thoughts on why that could be? as well as any other issues in my code.
Disclaimer: Im rather new to coding, and im trying to do this with what i know (scanner and random for example) i imagine there are more efficient ways to do what i wanna do, but im trying to do it with the tools that i have.
Two issues with your code :
Change
// this gets the ASCII value which is why you are getting weird numbers
// ASCII value of 1 is 49
int noOfDice = dieInput.charAt(0);
to
// this gets numeric value of the character
int noOfDice = Character.getNumericValue(dieInput.charAt(0));
int dieType = Character.getNumericValue(dieInput.charAt(2));
Use this to generate random numbers between 1 and dietype :
int minVal = 1;
int roll = (minVal + random.nextInt(dieType - minVal + 1);
With some OOP thinking, I'd write the Dice class. For example:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Dice {
private static final Random RANDOM = new Random();
private int sides;
private Dice(){
//no Dice constructor without the sides parameter
}
public Dice(int sides){
if (sides <= 0){
throw new RuntimeException();
}
else {
this.sides = sides;
}
}
public int getSides(){
return this.sides;
}
private int rollMyDice(){
return 1 + RANDOM.nextInt(this.sides);
}
public List<Integer> rollMyDiceManyTimes(int howManyRolling){
List<Integer> result = new ArrayList<>();
for (int i = 0; i < howManyRolling; i++){
result.add(rollMyDice());
}
return result;
}
}
Then, you can test it, (and/or rewrite the code to satisfied your goals):
public class Answer {
public static void main(String[] args) {
//test
Dice dice = new Dice(9);
System.out.println("I'm rolling the dice with "
+ dice.getSides()
+ " sides "
+ " ELEVEN TIMES "
+ dice.rollMyDiceManyTimes(11));
}
}
Of course, this is just a template I tried to provide to you...
Some output will be:
I'm rolling the dice with 9 sides ELEVEN TIMES [9, 4, 5, 2, 8, 7, 3, 8, 2, 1, 4]
You want to get the numbers from your string as integers, not chars. Here is one of many ways
String[] numbers = dieInput.split("d"); // "1d6" split into "1" and "6"
int noOfDie = Integer.parseInt(numbers[0]);
int dieType = Integer.parseInt(numbers[1]);
This will avoid the problem you're running into where you're getting the ascii value (which is also an int) from the char value you're getting back from the string.charAt() method.
Edit:
The numbers array in my snippet represents the result of the split input. Based on the expected input of two numbers separated by a d such as 1d6 or 3d10, the result would be an array with 2 items in it, the number before the d and the number after it. If, for example, you called the split method and the input string had multiple d characters, you'd get a bigger array. For example, 1d6d7 would result in an array with 3 items in it, "1", "6" and "7". Even though the contents are of type string, I contextually expect them their values to be numbers. Which is why in the following lines Integer.parseInt() is used to convert the value from a String to an int. This only works when the value of the string is a valid int.
I am writing a dice roll program. The code works fine in working out the face and number of frequencies. How I can calculate the percentage for the frequency of each face?
import java.util.Random;
public class Dice{
public static void main (String[] args){
Random random = new Random(); // Generates random numbers
int[] array = new int[ 7 ]; // Declares the array
//Roll the die 10000 times
for ( int roll = 1; roll <=10000; roll++ ) {
/*++array[1 + random.nextInt(6)];*/
int dice = 1 + random.nextInt(6);
++array[dice];
}
System.out.printf("%s%10s\n", "Face", "Frequency");
// outputs array values
for (int face = 1; face < array.length; face++) {
System.out.printf("%4d%10d\n", face, array[face]);
}
}
}
The frequency is just the count of each face divided by the total count.
for (int face = 1; face < array.length; face++) {
System.out.printf("%4d%10f\n", face, array[face] / 10000.0);
}
The division must be performed with a double value (otherwise, an integer division would be performed and the result would always be 0), explaining why I divided with 10000.0 and not 10000.
I also changed the String format from %10d to %10f because you want to print a decimal number, not an integer. See the Formatter Javadoc for the list of all token.
Also, I suggest you make a local variable holding the total count so as not to repeat it twice.
The question is as the title says, how would I get rid of duplicate values in an integer array? I want to have it so the user inputs five numbers, all ranging between 10 and 100. The catch is that I have to have it so that if the value they are inputting has already been input into the array it will not count. Here is the code I have so far:
public static void main(String[]args){
Scanner input = new Scanner(System.in);
int[] intArray = new int[5]; //max of 5 values
for(int i = 0; i < 5; i++){
System.out.println("Please enter your desired number that is between 10 and 100: ");
intArray[i] = input.nextInt(); //puts the value into the array
}
System.out.println(Arrays.toString(intArray)); //for test purposes to make sure the array was correctly taking in the values
}
}
System.out.println(Arrays.toString(intArray)); //for test purposes to make sure the array was correctly taking in the values
I am confused on how I would make it so if the user inputs a number that already exists in the array it will just not add it. Here is an example of what I mean, say the user inputs the numbers 15, 22, 46, 46, 77 once the program is done looping five times it will print out the following: [15, 22, 46, 77]. I am stuck on how to do this. Also I have edited out the if the number is between 10 and 100 if statements for it to be easier to read, and get to the main point at hand.
What about using a Set? A LinkedHashSet, in particular, allows you to do this in O(n) time and memory, while retaining the order of the inputs. And before you say "But I can't use a HashSet," you'll need its behavior for the optimal solution, so the followup question might be "How would I implement a LinkedHashSet, possibly baking the logic into my program?"
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Set<Integer> intSet = new LinkedHashSet<>();
int[] intArray = new int[5]; //max of 5 values
for (int i = 0; i < 5; i++) {
System.out.println("Please enter your desired number that is between 10 and 100: ");
intSet.add(input.nextInt());
}
int[] intArray = new int[intSet.size()];
int i = 0;
for (Integer val : intSet) {
intArray[i++] = val;
}
}
You're saying you want a variable number of numbers at the end, so an array is not the right choice here, use an ArrayList instead.
Something like:
List<Integer> intList = new ArrayList<Integer>();
int maxElements = 5; //Set max value here
for(int i = 0; i < maxElements ; i++)
{
System.out.println("Please enter your desired number that is between 10 and 100: ");
Integer newNumber = input.nextInt();
if(newNumber >= 10 && newNumber <= 100)
{
Boolean found = false;
foreach (Integer check : intList)
{
if (check == newNumber)
{
found = true;
break;
}
}
if (!found) intList.Add(newNumber);
}
else if(newNumber < 10 || newNumber > 100)
{
System.out.println("Enter a valid number next time, this number will not be counted in the results.");
}
}
Duplicate check: that inner loop I added checks if there is another element with the same value, and in that case skips the number as you said.
I wrote this without a computer, so I could have mixed some stuff up, but you get the general idea.
If you just have to select unique numbers from the numbers that a user will input, don't store them in an Array initially.
Instead, store them in a HashMap/Hashtable and then once the user input is finished convert it to an Array.
Another way of doing this would be to use the Set Collection. Add each number you receive to an instance of the Set and finally convert the Set to an Array. Set will maintain uniqueness by default.
public static void main(String[]args){
Scanner input = new Scanner(System.in);
int[] intArray = new int[5]; //max of 5 values
Set<Integer> uniques = new HashSet<Integer>();
for(int i = 0; i < 5; i++){
System.out.println("Please enter your desired number that is between 10 and 100: ");
uniques.add(input.nextInt()); //puts the value in the set
}
System.out.println(Arrays.toString(uniques.toArray())); //for test purposes to make sure the array was correctly taking in the values
}
A one liner would accomplish what you want:
Set<Integer> noDuplicates = new LinkedHashSet<>(Arrays.asList(intArray));
Do this after you read the values and store them in your intArray.
If you want to preserve the order in which the values were entered, use a LinkedHashSet, otherwise use just a HashSet.
A Set is a collection that cannot have duplicates.
make your array size 100 and using input as a index. before update array[input] = input, check the value of the index (input number) of the array.
use a map store input values as a key. before save the value in array, check whether key is in a map or not.
This question already has answers here:
Random Number Generator: mainly how to stop repetition of numbers. Java
(6 answers)
Closed 9 years ago.
Ok so the objective is to generate 6 random numbers per line/row. With x number of rows (set by the user via UserInput). Each row MUST have unique numbers (non-duplicated numbers). I'm pretty sure the numbers are unique, however I can't seem to get it to have multiple rows, and I cannot figure out for the life of me what part is preventing multiple rows.
package rtg;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class Array {
public static void main(String[] args) {
String name;
int noTickets;
int[] numbers = new int[6];
Set<Integer> randomNumbers = new HashSet<>();
Random rand = new Random();
int ticketCount = 1;
System.out.println("Please input your name");
name = UserInput.readString();
System.out.println("Please input the number of tickets you want");
noTickets = UserInput.readInt();
System.out.println("___________________________________________\n___________________________________________");
System.out.println("___________________________________________\n___________________________________________");
System.out.println("Name: " +name+ "\nNumber of Tickets: " +noTickets+ "\nNumbers: ");
for (ticketCount = 1; ticketCount <= noTickets; ++ticketCount){
while (randomNumbers.size() < 6) {
randomNumbers.add(rand.nextInt(50) + 1);
}
int i = 0;
for (Integer n : randomNumbers) {
numbers[i++] = n;
}
System.out.print( Arrays.toString(numbers) + "\n");
}
}
}
EDIT Thanks a lot everyone, I finally got there, turns out I put the array in the wrong place (it was outside the for loop so only made 1 set of random numbers) Fixed it now. Next challange; having a comparison program to scan 90+ sets of 6 unique numbers, and comparing if any of them match a different set (per row/set >.<)
You can stuff random integers into a Set<Integer> until it has six elements:
Set<Integer> randomNumbers = new HashSet<>();
Random rand = new Random();
while (randomNumbers.size() < 6) {
randomNumbers.add(rand.nextInt(50) + 1);
}
Alternatively, you can generate the numbers 1-50, shuffle them, and pick any six elements:
List<Integer> numbers = new ArrayList<>(50); // known capacity
for (int i = 1; i <= 50; ++i) { numbers.add(i); }
Collections.shuffle(numbers);
List<Integer> sixRandomNumbers = numbers.subList(0, 6);
The first solution does extra work whenever there is a collision; this extra work goes up the greater the ratio is of desired to total numbers. The second does extra work by having to deal with all 50 numbers; the extra work goes down the greater the ratio is of desired to total numbers. It's an interesting question where the cross-over point is.
EDIT (Responding to the edit to the original question) After you use one of the above methods to generate six distinct, random numbers, you need to put them into the variables you are going to use. One way (say, using the first method) is as follows:
int[] numbers = new int[6];
Set<Integer> randomNumbers = new HashSet<>();
Random rand = new Random();
while (randomNumbers.size() < 6) {
randomNumbers.add(rand.nextInt(50) + 1);
}
System.out.println("Six random numbers: " + randomNumbers.toString());
// if you need them as an `int` array:
int i = 0;
for (Integer n : randomNumbers) {
numbers[i++] = n;
}
The numbers array replaces your variables number1, ..., number6.
Use a data type which allows you to check if the int has already been created. For example, adding them to an ArrayList<Integer>.
ArrayList<Integer> numbers = new ArrayList<Integer>();
while(numbers.size() < 6) {
int num = rand.nextInt(50) + 1;
if(!numbers.contains(num)) {
numbers.add(num);
}
}
Of course, as #sanbhat says in the comments, you can use a Set<Integer> and avoid the if() conditional entirely in the loop. However I thought this would be more intuitive for a beginner who doesn't know that the Set API will not add a duplicate element.
Save a sorted list or more efficiently a set of the previously chosen values and check your current selection against the previous ones, if it was previously chosen try again.
If you know the valid range of your random numbers and if the size of that range is not prohibitive, one simple algorithm would be as follows:
Create an array with a size equal to your number range
Consecutively fill your array with the numbers in your number range
Iterate through the list an arbitrarily large number of times; generate two pseudorandom numbers that are within your array indices, and swap the two elements at those indices
After the iteration is complete, you will have an array of uniquely represented numbers that are all within your number range that appear in a random order. This nearly exactly simulates what happens when one shuffles a deck of cards.
You can then write a simple method to consecutively pop numbers out of your array each time it is called.
An advantage of this algorithm is that it can be implemented as an array of primitives, eg. int[], without any need for the Java Collections API.
I'm trying to put together a java program to do the following:
Prompt for and read in a number of integers to read
Create an array that can hold that many integers
Use a loop to read in integer values to fill the array
Calculate the average value in the array (as an integer)
This is what I have so far (although I'm pretty sure this is wrong):
public static void Average (Scanner keyboard)
{
System.out.println("Please insert number of integers to read in: ");
keyboard = new Scanner(System.in);
int f = keyboard.nextInt();
int value[]= new int[f];
//I don't know if I should use a while loop here or what the arguments should be
}
What should the conditions be, in order to set up the loop?
Let's look at what you need to calculate an average and what you have right now.
What you need
The total number of values
The values
Somewhere to keep the sum of values
What you have
The total number of values
A source from which to get new values
Now, from your code, you don't seem to have a place to add all your numbers. That's easy to fix; you know how to declare a new variable.
You also don't have the values, but you do have somewhere you can get them from. Since you also know how many numbers you need to sum up, you can use a loop to get that many numbers from your source.
All in all, you'll want your loop to run f times. In that loop, you'll want to get new a new number and add it to the rest. At the end, you should be able to derive the average from all that.
The better idea would be to prompt the user to enter all of the values at once, separated by spaces. IE
2 4 1 1 6 4 2 1
You can then call the split() function for Strings to split this into an array of Strings, then use the Integer.parseInt() function to turn this array of Strings into an array of ints.
Once you have your array of ints, it's a simple for loop to add all of the values together and divide by that array's length.
You can put a while loop or a for loop to input the numbers. Along with the input, keep taking the sum of the numbers. Since you have total number of values:
Average= (sum of numbers)/ total numbers.
I will write pseudo code so that it will force you to search more:
//Pseudo code starts after your array declaration
for loop from 0 to f
store it in values Array
save sum of numbers: sum= sum+values[i]
loop ends
calculate Average
public static void Average (Scanner keyboard)
{
System.out.println("Please insert number of integers to read in: ");
keyboard = new Scanner(System.in);
int f = keyboard.nextInt();
int value[]= new int[f];
double avg = 0;
for (int i = 0; i < f; i++)
{
value[i] = keyboard.nextInt();
avg += value[i];
}
avg /= f;
System.out.println("Average is " + avg);
}
I dont see a point of having array value. Or do you want some other kind of average ?
I wrote(with a friend) a code that calculates the average number:
package dingen;
import java.util.Scanner;
public class Gemiddelde {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
float maxCount = 0;
float avgCount = 0;
System.out.println("How many numbers do you want");
int n = sc.nextInt();
for(int i = 0; i < n; i++) {
System.out.println("Number: ");
float number = sc.nextInt();
maxCount = maxCount + number;
}
avgCount = maxCount / n;
System.out.println("maxCount = " + maxCount);
System.out.println("avgCount = " + avgCount);
}
}
the only thing you have to do is replace your class and package.
you wil get the message: How many numbers do you want?:
and then it wil ask you the amount of numbers you inserted.
example:
How many numbers do you want?:6
Number:6
Number:7
Number:8
Number:9
Number:93
Number:94
maxCount = 217.0
avgCount = 36.166668
I have hoped I helped you with your problem :)