I'm attempting to make this program
public class Statistics {
public static void main(String[] args) {
final int SIZE = 10;
int sum =0;
int[] numArray= new int [SIZE];
for (int c=0; c < SIZE; c++)
{
numArray[c]=(int)(Math.random()*6+1);
System.out.print( numArray[c]+ " ");
sum+=numArray[c];
}
System.out.println("\nSum of all numbers is " + sum);
System.out.println("\n Mean of numbers is " + (sum) / 5);
}
}
Calculate the mode of the randomly generated array.
I've seen source codes posted where they use a seperate method called computemode, but I don't kno where to place this second method within my code. I'm sorry, I am very very green when it comes to programming. I'm being taught Java as my first language and so far its overwhelming.
If someone could post the syntax with detailed instruction/explanation I'd be so grateful.
The mode is quite easy to compute. One way, assuming your inputs are bounded, is to simply have an array that tracks the number of occurrences of each number:
int[] data; //your data bounded by 0 and MAX_VALUE
int[] occurrences = new int[MAX_VALUE+1];
for ( int datum : data ) {
occurrences[newNumber]++;
}
Then figure out the index(es) in occurrences that has the highest value.
int maxOccurrences = Integer.MIN_VALUE;
int mode = -1;
for ( int i = 0; i < occurrences.length; i++ ) {
if ( occurrences[i] > maxOccurrences ) {
maxOccurrences = occurrences[i];
mode = i;
}
}
You would have to adjust this to handle multiple modes.
Related
I'm trying to write a code which will show the highest, lowest, the difference of them and the average of inputted 30 numbers.
But its not working and is showing the same result for both min and max numbers. Here is the code.
public class aa {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] daystemp = new int[30];
int i = 0;
int dayHot = 0;
int dayCold = 0;
while(i < daystemp.length){
daystemp[i] = input.nextInt();
i++;
}
int maxTemp = daystemp[0];
while (i < daystemp.length) {
if (daystemp[i] > maxTemp) {
maxTemp = daystemp[i];
dayHot = i + 1;
i++;
}
}
System.out.println(maxTemp);
int minTemp = daystemp[0];
while (i < daystemp.length) {
if (daystemp[i] < minTemp) {
minTemp = daystemp[i];
dayCold = i + 1;
i++;
}
}
System.out.println(minTemp);
int diff = maxTemp - minTemp;
System.out.println("The difference between them is"+diff);
double sum = 0;
while(i < daystemp.length) {
sum += daystemp[i];
i++;
}
double average = sum / daystemp.length;
System.out.println("Average was"+average);
}
}
After the first loop (the input loop), i value is daystemp.length (i.e. 30).
It's never reset to 0. So each while loop condition is false.
Add i=0 before the loops and do i++outside the ifblocks or your code will never end.
example:
i=0;
int maxTemp = daystemp[0];
while (i < daystemp.length) {
if (daystemp[i] > maxTemp) {
maxTemp = daystemp[i];
dayHot = i + 1;
}
i++;
}
A few notes about this solution:
By declaring the cumulative total double, no casting is required.
Because Java knows you want to convert int to double automatically if you assign an int to a declared double. Similary the fact that you want to express a result as double is implied when dividing a double by an int, such as when the average is taken. That avoids a cast also. If you had two ints and you wanted to produce a double you'd need to cast one or more of them, or in cases like a print statement where the compiler can't deduce the optimal type for the parameter, you'd need to explicitly cast to covert an int value to a double.
Not sure what OS you're running this on. The ideal situation would be to make it work on all platforms without requiring people type a magic word to end input (because how tacky). The easiest way to end input is to use the OS-specific end of input (end of file) key combination, and for Linux it's CTRL/D, which is how I explained it in the prompt. On another OS with a different end of input sequence you could just change the prompt. The trickiest would be if it is supposed to be truly portable Java. In that case I'd personally investigate how I could figure out the OS and/or End of File character or key combination on the current OS and modify the prompt to indicate to end input with whatever that is. That would be a bit of and advanced assignment but a very cool result.
Example illustrates use of a named constant to determine the array and is used limit the amount of input (and could be used to limit loop count of for loops accessing the array).
By setting the min and max to very high and low values respectively (notice the LOW value assigned to max and HIGH value assigned to min, those ensure the first legit temp entered will set the min and max and things will go from there).
Temperature Maximum, Minimum, Average and Difference Calculator
import java.util.Scanner;
public class TemperatureStats {
final static int MAX_DAYS = 31;
public static void main(String[] args) {
int[] dayTemps = new int[MAX_DAYS];
double cumulativeTemp = 0.0;
int minTemp = 1000, maxTemp = -1000;
Scanner input = new Scanner(System.in);
System.out.println("Enter temps for up to 1 month of days (end with CTRL/D):");
int entryCount = 0;
while (input.hasNextInt() && entryCount < MAX_DAYS)
dayTemps[entryCount++] = input.nextInt();
/* Find min, max, cumulative total */
for (int i = 0; i < entryCount; i++) {
int temp = dayTemps[i];
if (temp < minTemp)
minTemp = temp;
if (temp > maxTemp)
maxTemp = temp;
cumulativeTemp += temp;
}
System.out.println("High temp. = " + maxTemp);
System.out.println("Low temp. = " + minTemp);
System.out.println("Difference = " + (maxTemp - minTemp));
System.out.println("Avg temp. = " + cumulativeTemp / entryCount);
}
}
My question is why isn't the code generating the amount of numbers that the users enters? Right now the code is only generating one number. Here is the original question given to me:
"In your main method, prompt the user for a number n. Write a method
called assessRandomness that generates a random number between 1 and
100 'n' times and return the percentage of times the number was less than
or equal to 50. Call your assessRandomness method from main and display
the result to the user from main. Do not interact with the user from
within the assessRandomness method."
output:
How many random numbers should I generate? 10
<assume the random numbers generated were 11 7 50 61 52 3 92 100 81 66>
40% of the numbers were 50 or less
my code:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("how many random numbers should I generate?: ");
int number = in.nextInt();
assessRandomness(number);
}
public static double assessRandomness(int n){
int random = (int)(Math.random()*100);
int randomNumbersLessthan50 = 0;
if (random <= 50)
{
double getPercentage = random/randomNumbersLessthan50;
}
else
{
System.out.println(random);
}
return random;
}
I don't see any kind of loop within assessRandomness.
Try
for(int x = 1; x <= n; x++){ ... }
as first line in assessRandomness, it should finally look like
public static double assessRandomness(int n){
int counterLessThan50 = 0;
for ( int x = 1; x <= n; x++)
if( (int)(Math.random()*100) <= 50 ) counterLessThan50++;
return (double) counterLessThan50 / n;
}
There's no repetition in your code to do something n times.
Here's one way to do it in one line using a stream:
public static double assessRandomness(int n) {
return Stream.generate(Math::random).limit(n).map(r -> r * 100 + 1).filter(r -> r <= 50).count() / (double)n;
}
Note that converting Math.random() to a number in the range 1-100 is pointless; this will give the same result:
public static double assessRandomness(int n) {
return Stream.generate(Math::random).limit(n).filter(n -> n < .5).count() / (double)n;
}
And is easier to read.
At the moment, your assessRandomness method never uses the variable n.
At first you should initialize a variable which counts the number of created randoms that are bigger than 50 (this will be your retutn value). You should then do a loop from 0 until n. For each loop run you should create a random value between 0 and 100. Then you should check wether the value is bigger than 50. If so, count up your previously created variable. When the loop has finished, return the count variable and print it in the main method.
This should help you understand better how to do something like this.
public static void main(String[] args) {
System.out.println("how many random numbers should I generate?: ");
Scanner in = new Scanner(System.in);
int number = in.nextInt();
int[] arrayPlaceHolderInMainMethod = new int[number];
arrayPlaceHolderInMainMethod = generateRandomNumberArray(number);
assessRandomness(arrayPlaceHolderInMainMethod);
}
public static void assessRandomness(int[] inputArray) {
int randomNumbersLessthan50 = 0;
int randomNumbersGreaterthan50 = 0;
int random = 0;
for (int i = 0; i < inputArray.length; i++) {
random = inputArray[i];
}
if (random <= 50) {
randomNumbersLessthan50 += 1;
} else {
randomNumbersGreaterthan50 += 1;
}
System.out.println(">50: " + randomNumbersGreaterthan50 + " Less: " + randomNumbersLessthan50);
}
public static int[] generateRandomNumberArray(int numberPickedByUser) {
int[] arrayOfRandomNumbers = new int[numberPickedByUser];
for (int i = 0; i < numberPickedByUser; i++) {
arrayOfRandomNumbers[i] = (int) (Math.random() * 100 + 1);
}
return arrayOfRandomNumbers;
}
I am trying to write a program that accepts an integer from the user, then it should calculate this series S = 1/2! - 1/3! + 1/4! – 1/5! + .... all the way to 1/x! where x is the integer taken from the user, I already wrote this code to calculate the factorial of x :
import java.util.Scanner;
public class Factorial {
public static void main(String args[]){
Scanner x = new Scanner(System.in);
System.out.println("Enter a number: ");
int number = x.nextInt();
int fact = 1;
for (int i = 1; i <= number; i++){
fact = fact*i;
}
System.out.println("The factorial of "+number+" is "+fact);
x.close();
}
}
but still am not sure how to code the series, any tips would be really appreciated.
Also I am sorry if my code is not organized I don't know how to use stackoverflow tools ;( .
Ideally, what you want is to separate your code into multiple functions, and think logically.
Since you said you didn't want tips, I'll just try to put you on the right track.
Tip 1:
Separate your code into multiple functions
eg.
public static int factorial(int n){
int fact = 1;
for (int i = 1; i <= n; i++){
fact = fact*i;
}
return fact;
}
This allows you to split your code up into manageable chunks. Call each chunk at the appropriate time. This makes your code easier to read and more reusable
Tip 2:
One main class and the other class with functions.
Ideally, you want to create two classes, one which takes input from the user and one which contains all the functions you need. The main class taking the input will create an Object of the other class
public class Factorial{
public static void main(String args[]){
Scanner x = new Scanner(System.in);
System.out.println("Enter a number: ");
int number = x.nextInt();
Series s=new Series(number);
s.print();
x.close();
}
And in Series.java
public class Series{
int output;
int input;
Series(int i){
input=i;
//..here you calculate output
}
public int factorial(int n){
//.... the code
}
public void print(){
System.out.println("The calculation of " + input + " is " + output);
}
}
Tip 3:
Make a nice simple function to calculate the output. Sum up all your factorials over time
for (int i = 2; i <= input; i++) {
//if its even
if(i%2==0)
output = output + 1.0 / factorial(i);
else
output = output - 1.0 / factorial(i);
}
Add the following to your constructor and you'll have a well built Java program
Tip 4:: These sums are going to be decimals, not integers so you need to replace all your ints with doubles
First, you have to compute a sum of terms. The standard pattern is like
double sum = 0;
for (int i = first; i <= last; i++) {
sum += term(i);
}
then remark that
the first term is term(2) = +1/2!
the second term is term(3) = -1/3! = -term(2)/3
the third term is +1/4! = -term(3)/4
etc.
So you'll notice that each term can be easily obtained from the previous one.
This leads to
double sum = 0;
double term = (some value);
for (int i = first; i <= last; i++) {
term = (some expression involving i and previous term);
sum += term;
}
Exercise left as, huh, an exercise ?
UPDATED
How can you by using this method (Collatz conjecture) to find the number with the highest number of operations between, say 4 and 230.
Any guidance appreciated.
public static void main(String[] args) {
System.out.print("Enter a low integer ");
Scanner input = new Scanner(System.in);
int low = input.nextInt();
System.out.print("Enter a high integer ");
int number = input.nextInt();
maxendurance(number);
}
public static int maxendurance(int number) {
int count = 0;
System.out.print("The number " + number);
// need to loop this i suppose in relative to user input
while (number != 1) {
number = (number & 1) != 0 ? number * 3 + 1 : number >> 1;
count++;
}
System.out.println(" has endurance: " + count);
return number;
}
You will have to loop through all the numbers between low and high. Look into for-loops:
for(int number = low; number <= high; number++)
{
// do something with number
}
Somehow you will need to execute a for every number within the loop (hint: pass it in as a parameter). Then keep track of the number with the highest count.
Oh, and please name your methods more clearly than a and b - nobody will understand what they do without going through the code.
First of all, move the input out of method a:
public static void main(String[] args) {
System.out.print("Enter an integer to be checked: ");
Scanner input = new Scanner(System.in);
int number = input.nextInt();
a(number);
b();
}
public static int a(int number) {
int count = 0;
System.out.print("The number " + number);
[...]
Then you can use a simple for loop to iterate between low and high:
int bestNumber = -1;
int bestScore = -1;
for (int i = low; i <= high; i++) {
int score = a(i);
if (score < bestScore) {
bestNumber = i;
bestScore = score;
}
}
The result can then be found in bestNumber.
I am going to suggest a more advanced approach, in case relevant and incase anyone comes upon this. If you are concerned about time efficiency, Memoization or Dynamic Programming can help you, especially inverse dragon recursion.
I'll give you a hint. If you need more, just comment.
Take 3 for example. One transformation T has T(3)=10. If prior you had found it takes v transformations to take 10 to 1 and you stored (10,v) in a map, then instantly you know that it takes (v+1) steps to get 3 to 1.
I am creating a concentration game.
I have an buffered image array where I load in a 25 image sprite sheet.
public static BufferedImage[] card = new BufferedImage[25];
0 index being the card back. and 1 - 24 being the values for the face of the cards to check against if the cards match.
What I am tying to do is this I will have 4 difficulties Easy, Normal, Hard, and Extreme. Each difficulty will have a certain amount of cards it will need to draw and then double the ones it chosen. for example the default level will be NORMAL which is 12 matches so it need to randomly choose 12 unique cards from the Buffered Image array and then double each value so it will only have 2 of each cards and then shuffle the results.
This is what I got so far but it always seems to have duplicates about 99% of the time.
//generate cards
Random r = new Random();
int j = 0;
int[] rowOne = new int[12];
int[] rowTwo = new int[12];
boolean[] rowOneBool = new boolean[12];
for(int i = 0; i < rowOneBool.length; i++)
rowOneBool[i] = false;
for(int i = 0; i < rowOne.length; i++){
int typeId = r.nextInt(12)+1;
while(rowOneBool[typeId]){
typeId = r.nextInt(12)+1;
if(rowOneBool[typeId] == false);
}
rowOne[i] = typeId;
j=0;
}
the 3 amounts I will be needing to generate is Easy 6, Normal 12, and Hard 18 extreme will use all of the images except index 0 which is the back of the cards.
This is more or less in the nature of random numbers. Sometimes they are duplicates. You can easily factor that in though if you want them to be more unique. Just discard the number and generate again if it's not unique.
Here's a simple method to generate unique random numbers with a specified allowance of duplicates:
public static void main(String[] args) {
int[] randoms = uniqueRandoms(new int[16], 1, 25, 3);
for (int r : randoms) System.out.println(r);
}
public static int[] uniqueRandoms(int[] randoms, int lo, int hi, int allowance) {
// should do some error checking up here
int range = hi - lo, duplicates = 0;
Random gen = new Random();
for (int i = 0, k; i < randoms.length; i++) {
randoms[i] = gen.nextInt(range) + lo;
for (k = 0; k < i; k++) {
if (randoms[i] == randoms[k]) {
if (duplicates < allowance) {
duplicates++;
} else {
i--;
}
break;
}
}
}
return randoms;
}
Edit: Tested and corrected. Now it works. : )
From what I understand from your question, the answer should look something like this:
Have 2 classes, one called Randp and the other called Main. Run Main, and edit the code to suit your needs.
package randp;
public class Main {
public static void main(String[] args) {
Randp randp = new Randp(10);
for (int i = 0; i < 10; i++) {
System.out.print(randp.nextInt());
}
}
}
package randp;
public class Randp {
private int numsLeft;
private int MAX_VALUE;
int[] chooser;
public Randp(int startCounter) {
MAX_VALUE = startCounter; //set the amount we go up to
numsLeft = startCounter;
chooser = new int[MAX_VALUE];
for (int i = 1; i <= chooser.length; i++) {
chooser[i-1] = i; //fill the array up
}
}
public int nextInt() {
if(numsLeft == 0){
return 0; //nothing left in the array
}
int a = chooser[(int)(Math.random() * MAX_VALUE)]; //picking a random index
if(a == 0) {
return this.nextInt(); //we hit an index that's been used already, pick another one!
}
chooser[a-1] = 0; //don't want to use it again
numsLeft--; //keep track of the numbers
return a;
}
}
This is how I would handle it. You would move your BufferedImage objects to a List, although I would consider creating an object for the 'cards' you're using...
int removalAmount = 3; //Remove 3 cards at random... Use a switch to change this based upon difficulty or whatever...
List<BufferedImage> list = new ArrayList<BufferedImage>();
list.addAll(Arrays.asList(card)); // Add the cards to the list, from your array.
Collections.shuffle(list);
for (int i = 0; i < removalAmount; i++) {
list.remove(list.size() - 1);
}
list.addAll(list);
Collections.shuffle(list);
for (BufferedImage specificCard : list) {
//Do something
}
Ok, I said I'd give you something better, and I will. First, let's improve Jeeter's solution.
It has a bug. Because it relies on 0 to be the "used" indicator, it won't actually produce index 0 until the end, which is not random.
It fills an array with indices, then uses 0 as effectively a boolean value, which is redundant. If a value at an index is not 0 we already know what it is, it's the same as the index we used to get to it. It just hides the true nature of algorithm and makes it unnecessarily complex.
It uses recursion when it doesn't need to. Sure, you can argue that this improves code clarity, but then you risk running into a StackOverflowException for too many recursive calls.
Thus, I present an improved version of the algorithm:
class Randp {
private int MAX_VALUE;
private int numsLeft;
private boolean[] used;
public Randp(int startCounter) {
MAX_VALUE = startCounter;
numsLeft = startCounter;
// All false by default.
used = new boolean[MAX_VALUE];
}
public int nextInt() {
if (numsLeft <= 0)
return 0;
numsLeft--;
int index;
do
{
index = (int)(Math.random() * MAX_VALUE);
} while (used[index]);
return index;
}
}
I believe this is much easier to understand, but now it becomes clear the algorithm is not great. It might take a long time to find an unused index, especially when we wanted a lot of values and there's only a few left. We need to fundamentally change the way we approach this. It'd be better to generate the values randomly from the beginning:
class Randp {
private ArrayList<Integer> chooser = new ArrayList<Integer>();
private int count = 0;
public Randp(int startCounter) {
for (int i = 0; i < startCounter; i++)
chooser.add(i);
Collections.shuffle(chooser);
}
public int nextInt() {
if (count >= chooser.size())
return 0;
return chooser.get(count++);
}
}
This is the most efficient and extremely simple since we made use of existing classes and methods.