Random Numbers Test (Histogram) - java

I'm brand new to Java coding i'm trying to create a histogram with the following methods that were given to me. The comments are the instruction to each of our method that we will later use to create a main method and print a histogram. I have got up to method 3 and was able to compile everything fine but i'm not sure if i'm doing them right, I just know that they are compiling correctly up to method 4. I just don't know what to do for method 5.
/*
Method 1:
Find the maximun value in an array
*/
public static int max(int[]arr){
int maxValue = arr[0];
for ( int i=1; i < arr.length; i++ ){
if (arr[i] > maxValue){
maxValue = arr[i];
}
}
return maxValue;
}
/*
Method 2:
Compute a random integer in the range [a..b)
*/
public static int randomInteger(int a, int b){;
int randomNum;
randomNum = a+(int)(Math.random() * ((b-a)+1));
return randomNum;
}
/*
Method 3:
Draw a Simple histogram of the array arr.
*/
public static void drawHistogram(int[] arr){
for ( int i=0; i<arr.length; i++ ){
System.out.print((i*10+1)+"-"+(i*10+10)+":"+"\t");
for (int j=0; j<arr[i]; j++)
System.out.print("*");
System.out.println();
}
}
/*
Method 4:
Compute num random integers in the range [0..range) and put the frequency in arr[]
*/
public static void doSingleTest(int[] arr, int num, int range){
for (int i=1; i<=num; i++){
int random = randomInteger(0,range);
arr[random]++;
}
}
/*
Method 5:
Compute num pairs of random integers in the range [0..range) and put the frequency in arr[]
*/
public static void doPairsTesting(int[] arr, int num, int range){
}
public static void main(String[] args) {
int test[] = new int[]{1,2,3,4,6,11,7};
System.out.println("method1 = "+ max(test));
System.out.println("method2 = "+randomInteger(1,20));
drawHistogram(test);
doSingleTest(test,1,5);
System.out.println("method4 = "+Arrays.toString(test));
}

It's fault design int random = int randomInteger(range); I think you need to read docs abot java basics.
I fixed method4 in next way:
public static void doSingleTest(int[] arr, int num, int range){
for (int i=1; i<=num; i++){
int random = randomInteger(0,range);
arr[random]++;
}
}
For testing your methods, use next main method, it prints results to console or you can use Debugger in your IDE:
public static void main(String[] args) {
int test[] = new int[]{1,2,3,4,6,11,7};
System.out.println("mathod1 = "+ max(test));
System.out.println("mathod2 = "+randomInteger(1,20));
drawHistogram(test);
doSingleTest(test,1,5);
System.out.println("mathod4 = "+Arrays.toString(test));
}
And at last your method 5 must to return value of needed type or be void:
public static void doPairsTest(int[] arr, int num, int range){
}

For computing random integers, you might want to consider using the Random class. Here is some documentation: http://docs.oracle.com/javase/6/docs/api/java/util/Random.html
You can do this by declaring a Random object inside your class like this:
static Random randomGenerator = new Random();
And then within each of your methods, you can use randomGenerator.nextInt(n), where n will be the end of the range you want random numbers to be included. (exclusive of n, starting with 0).
For method 4, you probably want to set the return type to be an array. And then you can either leverage this randomGenerator, or given your current code, you'd have to pass in two parameters to your randomInteger method.
For method 5, you can simply use your doSingleTest method and then divide the entries of your array by 2 before returning the array. This works because if you find two 3s, your doSingleTest would have a frequency of 2 at the appropriate position. And dividing this by 2 would give you the number of pairs. Also you don't have to worry about odd numbers because the int type in Java simply drops remainders.
I also just noticed that you did not set a return type for method 5, so go ahead and set that to be int[]
And use a public static void main(String[] args) method to test your methods.

For method 5, are you referring to the dopairtest? In case so here is how I solved that:
static void doPairsTest(int[] arr3, int num2, int range3){
for (int i = 0 ; i < num2 ; i++) {
int rand2 = randomInteger(0, range3);
int rand3 = randomInteger(0, range3);
int randomPair = (rand2 * 10) + rand3 ;
System.out.println(randomPair);
arr3[randomPair] ++ ;
}
}
As you can see I just declared and assigned randomly generated values from my previous method into rand2 and rand 3 and then I added the two of them so they add up to a double digit.
Did you find out how to do the histogram? I am very confused on how to plot it based on the numbers and frequencies we generated.

public static void drawHistogram(int[] arr){
int n=0;
for (int i=1;i<=99;i++)
if (arr[i]>n)
n=arr[i];
for (;n>0;n--)
{
String r=" ";
for (int i=0;i<=99;i++)
if (n<=arr[i])
{
System.out.print(r+"*");
r=" ";
}
else
r+=" ";
System.out.println();
}
}

Related

How to get the value from each index?

I'm extremely new to Java and we're tasked to take random values of an array and pass them through a method where it adds all of them for a running total.
For the sumMethod I'd like to take each value from all the index (given by sizeOfArray) and add them together.
Thank you!
public static void sumMethod(double[] arrayOfDoubles){
//How to get the value from each indexes (given by sizeOfArray) and add them for the sum
int arrayLength = arrayOfDoubles.length;
System.out.println(arrayOfDoubles);
}
public static void main(String[] args) {
//1-3: Set up Scanner object to collect user's input on the size of array.
Scanner keyboard = new Scanner(System.in);
System.out.println("How many double numerical entries do you have?");
//4: Declare an array of size sizeOfArray
int sizeOfArray = keyboard.nextInt();
//Initialize array
double[] arrayOfDoubles;
arrayOfDoubles = new double[sizeOfArray];
for(int i = 0; i < sizeOfArray; i++){
//5: Use the Random number Class and walk over the array
Random randomNum = new Random();
arrayOfDoubles[i] = randomNum.nextDouble(0.0 , 100.0);
//6: Invoke SumMethod
sumMethod(arrayOfDoubles);
}
}
}
public static void sumMethod(double[] arrayOfDoubles) {
double sum = 0;
for (int j = 0; j < arrayOfDoubles.length; j++) {
sum += arrayOfDoubles[j];
}
}
This will work too, if you are not familiar with the for-each loop yet.
Additionally, it is better to use arrayOfDoubles.length in the loop, in case you edit the code later, and change the size, or add or remove an element.
For sumMethod, I'd say the first thing you could do is give it a return value rather than void, (public static double sumMethod). That way when you run that method in main you can hold onto the result it prints out.
I may be wrong but my understanding is that your goal is to take an array and sum up the values within. For that purpose, the following would be a way to do it.
public static double sumMethod(double[] arrayOfDoubles) {
double total = 0;
for (double num : arrayOfDoubles) {
total += num;
}
return total;
}

Adding plus 1 towards an array containing full of number via main class and another class

public class Main
{
public static void main(String[] args)
{
int[] num = {1,2,3,4};
System.out.println(Counter.add(num));
}
}
Class
public class Counter
{
public static int add(int[] numb)
{
for(int i=0;i<numb.length;i++){
numb[i]++;
System.out.println(numb[i]);
int result = result + numb[i];
}
return result;
}
}
I am trying to output the total number in the array list, but with a twist, having +1 to each number in the array list, so 1,2,3,4 would give me 14, as 1+2+3+4 = 10 + 4 (+1 to each number), do I have to use .split to give me the total amount of variable in the array to add onto the total addition?
Do I have to use .split to give me the total amount of variable in the array to add onto the total addition?
No. You can simply return the sum, plus the length of the Array. Also you declare result within the for loop, so it is only in scope within the loop. Move it outside of the loop
public static int add(int[] numb)
{
int result = 0;
for(int i=0;i<numb.length;i++){
System.out.println(numb[i]);
result += numb[i];
}
return result + numb.length;
}
Which, when called with the Array int[] num = {1,2,3,4}; outputs 14.

Need help randomizing numbers based on user input

public class numberCube {
public static int size;
public static int tosses;
public static int random;
public static int value;
public static int values;
public static void cubeSize(){
// Gets the range of numbers that are allowed to be randomized
String x = JOptionPane.showInputDialog
("How many numbers do you want on your cube?");
int size = Integer.parseInt(x);
}
public static void numTosses(){
// Gets the amount of times that a randomizer will loop
String y = JOptionPane.showInputDialog
("How many times do you want to toss the dice?");
int tosses = Integer.parseInt(y);
}
public static void randomizer(){
// creates the random numbers. Heres where the problem is. I need to be able //to allow the user to specify the range of numbers and how many times it will //be randomized
For example, for cubeSize() I could enter 3, and for numTosses() I could enter 5. A possible output would be: 1,1,3,2,3
}
}
}
You're duplicating the initialization of variables (ex: size,tosses,etc) here.
If want to manipulate a property of a specific class you need to use this keyword. So,
int size = Integer.parseInt(x); becomes this.size = Integer.parseInt(x);
int tosses = Integer.parseInt(y); becomes this.tosses = Integer.parseInt(y);
etc..
Then in your randomizer() method you could try something like :
Random random = new Random();
for (int i = 1; i <= this.tosses; i++) {
int value = 1 + random.nextInt(this.size);
System.out.println(value);
}
You mean something like this?
Random r = new Random();
for (int i = 0; i < numTosses; ++i) {
int rand = 1 + r.nextInt(cubeSize);
// use rand, which will be an integer from 1 to cubeSize (inclusive)
}

Testing a random number generator

I am having trouble printing out the first two columns of the results in a table but as I am new to programming I am having issues and wondering where the issue is in my code. The brief states I must create:
A parameterless static int method, randInt(), that will return a random integer in the range 0..9 inclusive. This method will include a call to Math.random().
A static void method named randTest that takes a single integer argument, n. This should perform the following actions:
Declare an int array of 10 elements named counts. This will be used to record how often each possible value is returned by randInt.
Call randInt n times, each time incrementing the count of the element of counts corresponding to the value returned.
Print the results to the console in a clear tabular form. The output should look like the following:
This is my code:
import java.util.Arrays;
public class RandNumGenerator {
public static int RandInt(){
double n = Math.random()*10;
return (int) n;
}
public static void randTest(int n){
int [] counts = new int [10];
for(int i=0;i<n;i++){
counts[i] = RandInt();
System.out.println(counts[i]);
}
}
public static void main(String[] args) {
int sampleSize = 1000;
System.out.println ("Sample Size: " + sampleSize);
String[] intArray = new String[] {"Value","Count","Expected","Abs Diff","Percent Diff"};
System.out.println(Arrays.toString(intArray));
randTest(10);
}
}
public static void randTest(int n){
Question for you to think about: What is the parameter here? Hint: It's not 10... What do you actually want to DO n times?
counts[i] = RandInt();
You really want to create 10 random numbers and store them into the array? Nope. You want to create "sampleSize" numbers and increase the array on the correct position. What would the correct position be?
counts[ correctPosition ] = counts[ correctPosition ] + 1;
...would be more correct, if you can figure out the correctPosition.
Also I would move the output from the main method to randTest() where you have everything together.

How can I prevent the overlapping random numbers

How would i prevent duplicating numbers from random numbers.
I need to generate 5 numbers between 1 and 9 that are each different.
I would often get same numbers like 23334, how can i prevent that?
Any help would be great!
int num2 = (int) Math.round((Math.random()*9) +1);
int num1 = (int) Math.round((Math.random()*9) +1);
int num5 = (int) Math.round((Math.random()*9) +1);
int num3 = (int) Math.round((Math.random()*9) +1);
int num4 = (int) Math.round((Math.random()*9) +1);
One option is to use shuffle algorithm (e.g. Fisher-Yates shuffle ) to generate random sequence from 1 to 9, then take first 5 numbers of the sequence
Further explanation on StackOverflow: https://stackoverflow.com/a/196065/950427
Set<Integer> set=new HashSet<>();
while (set.size()<5) {
set.add( Math.round((Math.random()*9) +1));
}
After the set is filled you have 5 unique random numbers.
UPDATE: just to illustrate Jared Burrows' comment
Create a List includes the numbers that you want (1 to 9).
Generate random number from 0 to (size of the list minus 1).
Remove one element by index from the above generated random number. And add the removed element to a array which to be returned as a results
public static void main(String[] args) {
int []answers= returnRandomNonRepeatingNumbers(5,0,9);
for(int answer: answers) {
System.out.println(answer);
}
}
public static int[] returnRandomNonRepeatingNumbers(int sizeYouWant, int poolStart, int poolEnd) {
List<Integer> pool=new ArrayList<Integer>();
for(int i=poolStart;i<=poolEnd;i++) {
pool.add(i);
}
int []answers=new int[sizeYouWant];
for(int i=0;i<sizeYouWant;i++) {
//random index to be pick and remove from pool
int randomIndex = (int) Math.round((Math.random()*(pool.size()-1)));
answers[i]=pool.remove(randomIndex);
}
return answers;
}
If the number of possible random values is small, you want to use shuffle.
List<Integer> values = IntStream.range(0, 10).boxed().collect(toList());
Collections.shuffle(values);
values = values.subList(0, 5);
If the number of possible random values is large, you want to test adding them to a Set (or the original list if small enough)
Set<Integer> valueSet = new HashSet<>();
Random rand = new Random();
while(valuesSet.size() < 5) valuesSet.add(rand.nextInt(9) + 1);
List<Integer> values = new ArrayList<>(valueSet);
Collections.shuffle(values, rand);
Note: you need to shuffle the set as it doesn't preserve order. e.g. the numbers 1,2,3 will always come out in that order with HashSet, not 3,2,1.
Floyd's subset selection algorithm is designed to do exactly what you want, and is extremely efficient even for large sets. Selecting m items from a set of n is O(m) average running time, independent of n. Here's a Java implementation.
/*
* Floyd's algorithm to chose a random subset of m integers
* from a set of n, zero-based.
*/
public static HashSet<Integer> generateMfromN(int m, int n) {
HashSet<Integer> s = new HashSet<Integer>();
for (int j = n-m; j < n; ++j) {
if(! s.add((int)((j+1) * Math.random()))) {
s.add(j);
}
}
return s;
}
One possible approach to this problem can be divide & conquer. Step of following describes the approach:
Say m is the minimum & n is the maximum, within what i wanna get x number of randoms
Choose a random p between m & n. Save it to an array of answer. decrease x by 1 as we get one answer to our problem.
Now take a q a random number between m & p-1, another r a random number between p+1 & n. Fill up the answer array with q & r decrease x 1 for q and another 1 for the r.
Now carry on this process recursively, until the lower bound (m) & higher bound (n) becomes equal or x becomes 0.
Benefit: benefit of this approach is that, in worst case, it's runtime will be O(x), where x is the number of random number required. The best case scenarion is also o(x), as i have to find at least n number of random. These two comprise average case to θ(x) complexity.
import java.util.Random;
class GenerateDistinctRandom{
static int alreadyPut = 0;
static Random rand = new Random();
public static int[] generateDistinctRandom(int howMany, int rangeMin, int rangeMax)
{
int randomNumbers[] = new int[howMany];
GenerateDistinctRandom.recursiveRandomGenerator(rangeMin, rangeMax, randomNumbers, howMany);
return randomNumbers;
}
private static void recursiveRandomGenerator(int rangeMin, int rangeMax, int[] storage ,int storageSize)
{
if(rangeMax - rangeMin <= 0 || GenerateDistinctRandom.alreadyPut == storageSize)
{
return ;
}
int randomNumber = GenerateDistinctRandom.rand.nextInt(rangeMax-rangeMin) + rangeMin;
storage[GenerateDistinctRandom.alreadyPut] = randomNumber;
GenerateDistinctRandom.alreadyPut++;
//calling the left side of the recursion
recursiveRandomGenerator(rangeMin, randomNumber - 1, storage, storageSize);
recursiveRandomGenerator(randomNumber + 1, rangeMax, storage, storageSize);
}
public static void main(String []args){
int howMany = 5;
int distinctNumber[] = GenerateDistinctRandom.generateDistinctRandom(howMany 0, 9);
for(int i = 0;i < howMany;i++)
{
System.out.println(distinctNumber[i]);
}
}
}
I suppose you would need to store the ones that have been generated into an array and compare the new random number to the list to ensure it is unique.
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
int[] numbers = new int[5];
int tempNumber = 0;
for(int numberCounter = 0; numberCounter < numbers.length;)
{
tempNumber = (int) Math.round((Math.random()*9) +1);
if(!contains(numbers, tempNumber)){
numbers[numberCounter++] = tempNumber;
}
}
}
public static boolean contains(final int[] numbersArray, final int tempNumber) {
for (final int numberFromArray : numbersArray) {
if (numberFromArray == tempNumber) {
return true;
}
}
return false;
}
I notice you did not use an array in your example, so in case you do not know how to use them yet, you could also make 5 variables.
int randomNumber = 0;
int firstNumber = Math.round((Math.random()*9) +1);
int secondNumber = 0;
while(secondNumber == 0){
randomNumber = Math.round((Math.random()*9) +1)l
if(randomNumber != firstNumber){
secondNumber = randomNumber;
}
}
And you could continue making while statements like that. But if you are supposed to know about arrays, you should definitely be using one to store the numbers.
How about this?
package com.se;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class TestRandom {
List<Integer> comp = new ArrayList<>();
int listSize = 20;
public void doTask() {
Random ran = new Random();
int i = 0;
while(i < listSize){
int randomNumber = ran.nextInt(80) + 1;
if(!comp.contains(randomNumber)){
comp.add(randomNumber);
i++;
}
}
for(Integer num : comp){
System.out.println(num);
}
}
public static void main(String[] args) {
TestRandom testRandom = new TestRandom();
testRandom.doTask();
}
}

Categories