I want to find distinct numbers in a queue but I can't use anything but a queue such as an array or etc.
Here is my code:
Queue distinct = new Queue(10);
Queue distincttemp1 = new Queue(10);
int count=0;
Random rnd = new Random();
boolean flag=true;
for (int i = 0; i < 10; i++) {
int x = rnd.nextInt(9);
System.out.print(x + " ");
distinct.enqueue(x);
}
System.out.println("");
I couldn't find a solution finding how many numbers are repeated except adding every each number to a queue. It should be simple with a few loops. Can you help me find an algorithm?
Input and output should be like this:
Queue: 4 8 5 8 4 3 2 8
Output: 5
You can use Queue and keep track of distinct numbers using HashSet because sets do not allow duplicate values.
Queue<Integer> distinct = new LinkedList<>();
Set<Integer> set = new HashSet();
Random random = new Random();
int number;
for(int i=0; i<10; i++){
number = random.nextInt(9);
System.out.print(number+" ");
distinct.add(number);
set.add(number);
}
System.out.println("Distinct "+set.size());
According to your example, your numbers are between 0 and 8. That means that a single Integer variable is more than enough to mark an occurrence of any of your numbers (we need only 9 bits for that).
Explanation
Keep track of distinct values
If a value x is generated, then an xth bit in the binary representation of the "marker" variable is set to 1.
int marker = 0;
...
int x = random.nextInt(9);
System.out.print(x + " ");
marker |= (1 << x);
...
Number of distinct values
Then, once the loop is complete, number of set bits in the marker corresponds to the number of different values generated in the loop.
...
System.out.println(Integer.bitCount(marker));
...
Full Code
Random random = new Random();
int marker = 0;
for (int i = 0; i < 10; i++) {
int x = random.nextInt(9);
System.out.print(x + " ");
marker |= (1 << x);
queue.add(x);
}
System.out.println("\n" + Integer.bitCount(marker));
4 7 1 4 0 1 4 0 7 8
5
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.
Can someone explain to me how this code works?
It lets the user input numbers up until 1000, then it prints the original inputted numbers, the even and the odd, all in a separate array. But I just don't understand the parts where there is gem++ and gem1++ when it outputs the even and odd not the number of the even and odd numbers.
And after putting this
double even[] = new double[gem];
double odd[] = new double [gem1];
why does it need to repeat gem=0 and gem1=0 again? I'm so sorry if I ask too many question, I'm just confused, I just learned java last week.
public class wutt {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("Enter no. of elements you want in array : ");
int n = s.nextInt();
if (1 <= n && n <= 1000) {
double a[] = new double[n];
int gem = 0, gem1 = 0;
System.out.println("Enter all the elements : ");
for (int i = 0; i < n; i++) {
a[i] = s.nextInt();
if (a[i] % 2 == 0)
gem++;
else
gem1++;
}
double even[] = new double[gem];
double odd[] = new double[gem1];
gem = 0;
gem1 = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] % 2 == 0) {
even[gem] = a[i];
gem++;
} else {
odd[gem1] = a[i];
gem1++;
}
}
System.out.println("Original: " + Arrays.toString(a));
System.out.println("Odd: " + Arrays.toString(odd));
System.out.println("Even: " + Arrays.toString(even));
} else
System.out.print("Invalid input");
}
}
If you want the program stops after the user enters a number greater than 1000 o less than 0 you need to add the break statement in your if condition.
if (size < 0 || size > 1000) {
System.out.println("Size must be between 0 and 1000");
break;
}
the code before double even[] = new double[gem];
double odd[] = new double [gem1]; is trying to get the number of odds occurred and the number of even occurred and put all inputted elements in array a.
after all that ,now what we got is a array of numbers called a containing all the inputted elements. and two numbers called gem and gem1, which contains the number of odds occurred and the number of even occurred.
so
we get gem(numberOfEvens), gem1(numberOfOdds) and list a
next, we need to put all odds from a to a new array called odd[] with size gem1, and
put all evens from a to a new array called even[] with size gem. at this point, the duty of variable gem1 and gem is done. they become useless.
now we need to go through the list and pick the odd and even out and put them in the array one by one in a sequential way. that's why we need two new variables with 0 initialized.
in this case, because gem and gem1 are useless aready, they are reassigned to help manipulate the tree arrays a , odd[] and even[]
So the user inputs the number of elements he/she wants in the array (n)
double a[] = new double[n]; // a is the array that is initialised to accommodate n elements
int gem = 0, gem1 = 0; // gem is the counter for "even" numbers and "gem1" the counter for odd numbers, and like every good counter, they start at 0
System.out.println("Enter all the elements : ");
for (int i = 0; i < n; i++) { // so we ask the user to input n elements
a[i] = s.nextInt(); // here we read every input and put it in the a array
if (a[i] % 2 == 0) // if the new number is even
gem++; // we increase the even counter "gem"
else // otherwise, when it is an odd number
gem1++; // we increase the odd counter
}
double even[] = new double[gem]; // now we create a new array where we want to hold all the even numbers, we do that by telling it how many even numbers we have counted before (gem)
double odd[] = new double[gem1]; // and a new array for all odd numbers (gem1 was our counter)
gem = 0; // now we reinitialise the counters, because we want to start from the beginning
gem1 = 0;
for (int i = 0; i < a.length; i++) { // in order to copy all numbers from the a array into the two other arrays for even and odd numbers, we iterate over the whole length of the a array. i is the index for the "a" array
if (a[i] % 2 == 0) { // ever even number we encounter
even[gem] = a[i]; // we put in the even array
gem++; // while gem, the "even numbers counter" is our index for the "even" array
} else {
odd[gem1] = a[i]; // odd numbers are for the odd array
gem1++; // while the former "odd numbers counter" now serves as our "odd" array index
}
}
and that's pretty much it. First the user inputs all numbers in a single array and simply counts how many odd and how many even numbers where inputted,
then two new arrays are created, one for the even and one for the odd numbers and since we counted them, we know how big these two new arrays have to be.
And finally all numbers are again iterated over and put in their according array.
At the end you have 3 array, one that holds all numbers, one that holds the even numbers and one with only the odd numbers.
EDIT
here are a few minor changes you could make without changing the nature of that method:
double allNumbers[] = new double[n]; // "allNumbers" is way more specific than "a"
int oddCounter = 0; // "oddCounter" instead of "gem"
int evenCounter = 0; // numbers in variables like "gem1" is really bad practice, because numbers don't say anything about the nature of the variable
System.out.println("Enter all the elements : ");
for (int i = 0; i < n; i++) {
allNumbers[i] = s.nextInt();
if (allNumbers[i] % 2 == 0) {
evenCounter++;
} else {
oddCounter++;
}
}
// until here nothing changes but the names
double even[] = new double[evenCounter];
double odd[] = new double[oddCounter];
int oddIndex = 0; // and here we create new variables, instead of reusing old ones
int evenIndex = 0; // there is absolutely no performance gain in reusing primitives like this - it's just confusing
for (int i = 0; i < allNumbers.length; i++) {
if (allNumbers[i] % 2 == 0) {
even[evenIndex++] = allNumbers[i]; // the "++" can be done directly in the first expression. that's just to make it shorter.
} else {
odd[oddIndex++] = allNumbers[i]; // it is not more performant nor easier to read - just shorter
}
}
EDIT (again)
This is how the arrays look like, say when you enter 4 numbers:
gem = 0
gem1 = 0
n = 4 // user said 4
a = [ , , , ] // array a is empty but holds the space for 4 numbers
a = [1, , , ] // user enters 1
^
i=0
gem1 = 1 // 1 is an odd number -> gem1++
a = [1,4, , ] // user entered "4"
^
i=1
gem = 1 // 4 is an even number -> gem++
a = [1,4,2, ] // user entered "2"
^
i=2
gem = 2 // 24 is an even number -> gem++
a = [1,4,2,7] // user entered "7"
^
i=3
gem1 = 2 // 7 is an odd number -> gem1++
then we fill the other arrays
even = [ , ] // gem is 2, so we have 2 even numbers
odd = [ , ] // gem1 is 2, so we have 2 odd numbers
a = [1,4,2,7]
^
i=0
odd[1, ] // for i=0, a[i] is 1, which is an odd number
a = [1,4,2,7]
^
i=1
even = [4, ] // for i=1, a[i] is 4, which is an even number
a = [1,4,2,7]
^
i=2
even = [4,2] // for i=2, a[i] is 2, which is an even number
a = [1,4,2,7]
^
i=3
odd = [1,7] // for i=3, a[i] is 7, which is an odd number
and in the end you have
a = [1,4,2,7]
even = [4,2]
odd = [1,7]
This is what I tried so far in my app.
I got this code by searching it from Google.
Inside the Button OnClick() I called the Arandom() method:
public void Arandom(View view) {
final int SET_SIZE_REQUIRED = 4;
final int NUMBER_RANGE = 70;
Random random = new Random();
Set set = new HashSet<Integer>(SET_SIZE_REQUIRED);
while(set.size()< SET_SIZE_REQUIRED) {
while (set.add(random.nextInt(NUMBER_RANGE)) != true) ;
}
assert set.size() == SET_SIZE_REQUIRED;
ArrayList<Integer> Elements = new ArrayList<>(set);
Log.i("Elements","A:" + Elements.get(0));
Log.i("Elements","B:" + Elements.get(1));
Log.i("Elements","C:" + Elements.get(2));
Log.i("Elements","D:" + Elements.get(3));
}
Now I am able to get four unique random numbers by this code but the problem is there sum is greater then 60. Let me explain it little bit.
When I run the code I get:
A:61
B:45
C:31
D:49
This is the screen shot of my log cat
So I want the sum of all the numbers should be in the specified range (which is 1 to 60).
e.g: A = 20 , B = 25 , C = 3 and D = 11 then their sum is 59 which is within the range
Now another e.g: Suppose A = 5 , B = 22 , C = 18 and D = 3 then their sum will be 48
When we Add A,B,C,D then their sum should not exceed the range that is 60
I am new to Android and Java, and I am learning on my own by searching some materials on Google.
Let's say your target sum is T. It's easiest if you try to pick the numbers in descending order (you can shuffle them afterwards, if you want).
The largest number you can pick for the 1st of four numbers is T-6, because you need to pick 3, 2 and 1 for the smaller numbers.
The smallest number you can pick is the one where n+(n-1)+2+1 = T, so T/2+1.
So, pick the first number in the range (T/2+1) to T-6.
Then repeat the process to pick the third-largest and second-largest, applying similar logic to determine the possible range. There should be no choice in the smallest number, it's just whatever else you need to add to make the final sum.
Note that you need to take care with rounding of things like the T/2.
I made the return type an int[]. You know how big you want to make the set, so there is no need to use sets or lists. The input parameter is changed to SET_SIZE_REQUIRED instead of using view. Make sure that a funtion only has one purpose and not do a calculation and change on a view at the same time.
Replace the 60f to something else if you want the sum to be more or less than 60.
public int[] Arandom(int numberOfValues) {
int[] values = new int[numberOfValues];
int sum = 0;
for(int i = 0; i < numberOfValues; i++){
values[i] = (int)(Math.random() * 100);
sum += values[i];
}
float multiplier = 60f / sum;
for(int i = 0; i < numberOfValues; i++){
values[i] = (int)(values[i] * multiplier);
Log.i("Value " + (i + 1), values[i]);
}
return values;
}
Or just do this:
public int[] Arandom(int numberOfValues) {
int[] values = new int[numberOfValues];
for(int i = 0; i < numberOfValues; i++){
values[i] = (int)(Math.random() * (60f / numberOfValues));
Log.i("Value " + (i + 1), values[i]);
}
return values;
}
I am trying to make a program that lets the user choose how many times he want to throw the dice, and then every value of the thrown dice should be counted. In the end of the program the user should see how many times he threw 1, 2, 3 etc. This is a program to see if every number has an equal chance of being shown.
I encountered problems in the beginning of my code since I don't know how to let the computer throw the dice lets say 1000 times and then save every value from those thrown dices. This is what I have so far:
import java.util.Scanner;
public class Uppgift4_5
{
public static void main(String[] args)
{
Scanner inputReader = new Scanner (System.in);
System.out.println("How many times do you want to throw the dice:");
int amount = inputReader.nextInt();
int [] dice = { 1, 2, 3, 4, 5, 6 };
int random = 0;
for (int i = 0; i < amount; i++)
{
random = (int) (Math.random () + 1);
}
}
}
The problem I'm facing is that it only saves one random number and then loops that number 6 times.
As you can see I have not come far, I just need to know how I can save and count every individual thrown dice. And then I think I am going to use a switch and case to somehow save that(any suggestions there would also be helpful). Any suggestions or answers would be helpful. Thanks.
I would use a HashMap to store the value of the throw (1 to 6), as well as storing the number of times you got that value (increment by one for each):
public static void main(String[] args) {
Scanner inputReader = new Scanner(System.in);
System.out.println("How many times do you want to throw the dice:");
int amount = inputReader.nextInt();
Map<Integer, Integer> rolls = new HashMap<>();
for (int i = 1; i < 7; i++) {
rolls.put(i, 0);
}
for (int i = 0; i < amount; i++) {
int value = (int) (Math.random() * 6 + 1);
rolls.put(value, rolls.get(value) + 1);
}
for (Map.Entry<Integer, Integer> entry : rolls.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
The first for-loop initializes the keys 1 to 6 in the hashmap.
The second for-loop computes X number of dice throws and adds them to the hashmap.
The third for-loop iterates through the values in the hashmap and prints out the results.
Output:
How many times do you want to throw the dice:
500
1: 92
2: 88
3: 72
4: 78
5: 81
6: 89
EDIT: If you want to get the average and the median you could do the following:
double average = 0;
int[] storedSums = new int[6];
int i = 0;
for (Map.Entry<Integer, Integer> entry : rolls.entrySet()) {
int sum = entry.getValue();
average += sum;
storedSums[i++] = sum;
System.out.println(entry.getKey() + ": " + sum);
}
Arrays.sort(storedSums);
System.out.println("Average: " + (average / 6));
System.out.println("Median: " + storedSums[2]);
The average is simply the process of summing the values and dividing by the amount. The median with a hashmap is a little bit more tricky, however. The better choice here is to use an Array or an ArrayList to store the different values, then sort them and finally pick the middle element (either index 2 or 3).
I opted for an array in this case because we know the size of it.
EDIT: Regarding your last request:
To get the dice the median value corresponds to, I simply convert the array to a list, and use the indexOf method with the known value:
int medianDice = Arrays.asList(storedSums).indexOf(storedSums[2]);
System.out.println("Median: " + storedSums[2] + ", which belongs to dice: " + medianDice + ".");
It's a bit more complicated to get the value of the dice for the average (since this number isn't represented by one of the dies). You would have to use the average to find the closest value in the array, and then output the index for that value.
You are over writing the same random int value again and again, so use an array of int to store the values as shown below:
int[] random = new int[amount];//declare an array
Random randomNumber = new Random();
for (int i = 0; i < amount; i++) {
random[i] = randomNumber.nextInt(7);
}
Also, use java.util.Random nextInt() with an upper bound (in your case, the max value for the dice can be 6, so use upper bound as 7) to generate the random numbers as shown above.
you could use an ArrayList to store the random numbers and later process it when needed.
List<Integer> listOfNumbers = new ArrayList<>(amount);
Random generator = new Random();
for (int i = 0; i < amount; i++)
{
listOfNumbers.add(generator.nextInt(7));
}
Also, your current algorithm for the random numbers is incorrect, you should use the Random class to generator random numbers between 1 - 6 (inclusive).
import java.util.Scanner;
import java.util.Random;
public static void main(String[] args){
Scanner inputReader = new Scanner(System.in);
System.out.println("How many times do you want to roll the dice:");
int num_rolls = inputReader.nextInt();
int NUM_SIDES_ON_DICE = 6;
int[] results = new int[NUM_SIDES_ON_DICE]
Random rand = new Random();
for (int i = 0; i < num_rolls; i++) {
results[rand.nextInt(NUM_SIDES_ON_DICE)] += 1
}
for (int i = 0; i < dice.length; i++) {
System.out.println("Number of " + (i+1) + "'s thrown: " + results[i]
}
}
Version with stream:
new Random()
.ints(amount, 1, 7).boxed()
.collect(Collectors.groupingBy(s -> s))
.forEach((k, v) -> System.out.println(k + ": "+v.size()));;
Here is the deal: I have a java code that generates a random number between two numbers and it works just fine. But i'm trying to achieve something. I want it in such a way that after the first number has been generated, when it recalls it, it doesn't generate that same number. For instance, if number 4 is generated, i want it now to be included among the possible generated numbers for the second time. To make things a little bit clear, here's my code.
int Maximum=10;
int Minimum=1;
int r;
r = (int)(Math.random() * Maximum) + Minimum;
is there anything i can do to make the code above not to generate a particular number between 1 and 10? Thanks.
You could fill a collection and simply removed a randomly selected number:
List<Integer> nums = new ArrayList<>();
for (int i = /* start */; i < /* end */; i++) {
nums.add(i);
}
//Elsewhere
Random rand = new Random();
int get = nums.remove(rand.nextInt(/* end */);
/* end */--;
This may be a bit slower initially for large amounts of numbers but the end result is a lower time-complexity on your checks for new numbers (whereas a while loop could in theory be O(∞n) if I'm not mistaken)
Alternatively, use Collections#shuffle
This doesn't seem like random number generation, it seems like randomly shuffling a Collection.
In Java 8:
public static void main(String[] args) {
final int min = 0;
final int max = 10;
final List<Integer> nums = IntStream.rangeClosed(min, max).
boxed().
collect(toList());
Collections.shuffle(nums);
nums.forEach(System.out::println);
}
Output:
3
10
5
0
8
7
9
2
1
4
6
Each number [0, 10] appears only once in a random order.
if you just want to exclude a single number replace this:
r = (int)(Math.random() * Maximum) + Minimum;
with this:
while( ( r = (int)(Math.random() * Maximum) + Minimum) == excludedNumber );
ArrayList<Integer> intList = new ArrayList<Integer>();
int Maximum=10;
int Minimum=1;
int r;
int[] intArray = new int[6];
for(int i=0; i<intArray.length; i++){
r = (int)( Minimum+ (Math.random()* (Maximum-Minimum+1)) );
if(!intList.contains(r)){
intList.add(r);
intArray[i]=r;
System.out.println(r);
}
else{
System.out.println(r+ "is a duplicate generated earlier, not putting in array again");
i--;
}
}