Java recollecting the randomly chosen enums and summing it all up - java

A mere continuation of this article
Java How to get the sum up all the of the values of each enum
full source code below
http://pastebin.com/VMGUJmeZ
I have this For loop below, and what I am here to ask you guys for today is how I could recollect all of the randomly chosen enums, and sum up all their values.
for (int i = amount; i > 0; --i){//determines the amount of cycles.
Junk randomX = Junk.values()[random.nextInt(Junk.values().length)];
//randomly picks an enum
System.out.println(randomX);
}
Below me is the solution I did which basically declared a int sum, initialize it and put it in the for loop to collect the values of the enums
for (int i = amount; i > 0; --i){
Junk randomX = Junk.values()[random.nextInt(Junk.values().length)];
//randomly picks an enum
System.out.println(randomX);
for(Junk o : Junk.values()){
sum += o.getValue();
//sorry, I had sum declared and initialized outside of the loop.
System.out.println(sum);
}
}
sadly, the output was not desirable
Dresser
0
150
400
650
650
650
...
I understand that I am basically asking others to help me in writing code for me, but I am unsure of how else to do this.
Also I understand it might be impossible to do considering that the only way to get the sum of the enum's value is by doing it outside of the for loop, which will then make the solution impossible as it will only get all of the values.
Perhaps there is something besides a for loop I could use, that someone could recommend me in using.

You have a second loop
for(Junk o : Junk.values()){
sum += o.getValue();
//sorry, I had sum declared and initialized outside of the loop.
System.out.println(sum);
}
which is not neccessary. Simply replace this part by
sum += randomX.getValue();
System.out.println(sum);

int sum = 0;
for (int i = amount; i > 0; --i){
Junk randomX = Junk.values()[random.nextInt(Junk.values().length)];
//randomly picks an enum
System.out.println(randomX);
sum += randomX.getValue();
System.out.println(sum);
}
System.out.println("grand total: " + sum);

Related

Java - my while loop works, but my for loop doesn't - having trouble converting it

I assume that if I can't convert my while loop into a for loop, then I don't fully understand the concepts here. Here's my working while loop:
(I am trying to implement a program, which calculates the sum 1+2+3+...+n where n is given as user input.)
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter a number: ");
int number = Integer.valueOf(scanner.nextLine());
int sum = 0;
int i = 0;
while (i < number) {
i++;
sum += i;
}
System.out.println(sum);
I was looking at this user's answer here: https://stackoverflow.com/a/36023451/11522261
and tried to implement it, but it's not working.
.....
for (i = 0; i < number; i++){
sum += i;
}
System.out.println(sum);
It looks like the conditions of For Init expression statement and ForUpdate are set right, but I'm having trouble understanding the differences here.
Also, it looks like this exercise is trying to teach loops to solve iterative problems. But I suspect that this isn't helping me practice recursion. Perhaps there is a recursive solution to this problem which would be better. Just thinking out loud here. Thanks!
The difference is that in your while loop, you're incrementing i before adding it to sum, but in your for loop, it's after.
If the while is producing the right result, you can adjust your for by starting at 1 instead of 0 and continuing while <= number instead of < number.
For completeness, here's how your current for loop works:
i = 0
If i < number is not true, exit the loop; otherwise, continue to Step 3
sum += i (i is still 0)
i++
Goto Step 2
On the second pass, i < number is 1 < number so still true if number is greater than 1, so you go to Step 3, do sum += i while i is 1, then continue.
Eventually i < number isn't true anymore, and the loop exits.
For problems like this, the best approach is usually to use the debugger built into your IDE to step through the code statement by statement, looking at the values of variables as you go. That can reveal how things work really well. This article may be helpful: How to debug small programs
Since you are incrementing the value of i before adding it to sum in the while loop, the same thing needs to be done in case of for loop as well. Given below is the implementation using the for loop:
for (i = 0; i++ < number; ){
sum += i;
}
System.out.println(sum);
Use <= instead of <. This will solve Your problem, and make sure you understand why will the following code would work. I would recommand you to use a paper and pencil and start writing down the values of i and sum after every iteration.
for (i = 1; i <= number; i++) {
sum += i;
}

Java returning numbers below the avg

ne of my projects assigned was to create an array for 10 variables which the user inputs and to have the program output the average of the input number as well as listing the numbers below the average. I am able to obtain the average without an issue but my code to return the numbers below the average seems to not be doing the job. For example if I input into the array the values [1,2,3,4,5,6,7,8,9,10] the average outputs as 5.5 (which is good) but the output I want from BelowAverage is 1,2,3,4,5 can anyone help me?
public static double BelowAverage(ArrayList<Double> Averages) {
int i, aveless = 0; double avg = 0;
for(i = 0; i < Averages.size(); i++)
avg = Averages.get(i);
avg /= Averages.size();
for(i = 0; i < Averages.size(); i++)
if(Averages.size() < avg)
aveless++;
return aveless;
}
No need to use wrappers, you could use double instead of Double.
Your variable naming is weird, why do you have an ArrayList of averages instead of numbers?
Follow Java naming conventions:
firstWordLowerCaseVariable
firstWordLowerCaseMethod()
FirstWordUpperCaseClass
ALL_WORDS_UPPER_CASE_CONSTANT
and use them consistently
You already have a method that calculates the average, why not use it?
So, for example, your code might look like this (with slight modifications):
public static int belowAverage(List<Double> numbers) {
double avg = calculateAverages(numbers); //Go, get the average using the method you already have
int aveless = 0;
for (int i = 0; i < numbers.size(); i++) {
if (numbers.get(i) < avg) { //Instead of comparing the numbers array size, compare the number against the average.
aveless++;
}
}
return aveless;
}
I added opening and closing curly braces for the for loop as I think it's easier to read that way.
I also changed the return type to int instead of double on this method as you only want to count, so, decimal point is not needed and moved the System.out.println() call inside the calculateAverage() method to the main method.
I also changed the parameter type to the interface one (from ArrayList to List)
Your problem seems to bee on this line:
if(Averages.size() < avg) aveless++;
You should be checking Averages.get(i) < avg instead, otherwise what is the point of looping?
If I understand correctly, and you want a list with all the numbers below the average, you should change the return value and the code, like this:
public static ArrayList<Double> BelowAverage(ArrayList<Double> Averages) {
// You already have a method for calculating the average, so use it
double avg = CalculateAverages(Averages);
ArrayList<Double> aveless = new ArrayList<Double>();
int i;
for(i = 0; i < Averages.size(); i++){
double number = Averages.get(i);
if(number < avg){
aveless.add(number);
}
}
return aveless;
}
There are several problems with your code. Let's go through them one at a time.
First problem:
for(i = 0; i < Averages.size(); i++)
avg = Averages.get(i); //this line
avg /= Averages.size();
You are simply reassigning the value of avg in the loop. What you want to do is to keep adding values to it. Replace = with += to get avg += Averages.get(i);.
Second problem:
for(i = 0; i < Averages.size(); i++)
if(Averages.size() < avg)
aveless++;
Here you are checking whether avg is larger than the size of the list which is not what you want to be doing. What you wonder is whether avg is larger than the values in the list. You need to replace Averages.size() with Averages.get(i). This is a relatively easy mistake to spot because the loop is not really achieving anything right now, so look out for things like this.
Edit: There are a few other problems as well. avg should be a double and not an int, because ints cannot store decimal places and there is no guarantee that your average is a whole number, so you will get a rounding error. Furthermore, your method should return an int instead of a double because "the number of values below average" is always an integer.
To count the number of 'numbers' which have less value than the average, you should compare each element inside that array with the average, not with the size of the array. Try it as follows:
public static double BelowAverage(ArrayList<Double> Averages) {
int i, aveless = 0; double avg = 0;
for(i = 0; i < Averages.size(); i++)
avg = Averages.get(i);
avg /= Averages.size();
for(Double a : Averages)
if(a < avg) aveless++;
return aveless;
}

array index not incrementing (need to do casting in square brackets)

I have some doubts as to why the value of index is not incrementing here.
The reason why I have declared my array like that is because I need to store n natural numbers where (1 ≤ n ≤ 1012), so numbers are large which is why I have taken an array of type long, but then I get an error that I cannot put any long value in the group, which is why I cast it to int. Is there any way to declare an array for this type of condition, as I want a large number of indexes, and I can not put a long number in the [ ].
hope you guys understand my problem
CODE:
import java.util.Scanner;
class Error{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
long n = in.nextLong();
long array[] = new long[(int) n];
long index = 0;
for (int j = 1; j <= n; j++) {
if (j % 2 != 0) {//odd
array[(int) index++] = j;
System.out.print(" " + array[(int) --index]);
System.out.print(index);// index value -> always 0 why??
System.out.print(j);
}
}
System.out.println();
}
}
OUTPUT:
Unix-Box ~/Desktop$ javac Error.java
Unix-Box ~/Desktop$ java Error
10
101 303 505 707 909
Unix-Box ~/Desktop$
the middle value is of index and it is always 0
what i shout it to be like
10
101 313 525 737 949
Unix-Box ~/Desktop$
According to
https://www.quora.com/What-is-the-maximum-size-of-the-array-in-Java,
the max size of an array is 2147483647 theoretically, but in practice we would want to use 2147483600 to be safe. Declaring the array as type long will mean that long values can be stored inside. Maybe you can use a two dimensional array to store a long n amount of values. Something like--
public static void main(String[] args)
{
System.out.println("enter the size of the array:");
Scanner in = new Scanner(System.in);
long n = Long.parseLong(in.nextLine());
int secondIndex = 2147483600;
int firstIndex = ((int)(n/secondIndex))+1;
if(secondIndex > n)
{secondIndex = (int)n;
}
else{int leftover = (int)(n%secondIndex);
secondIndex = secondIndex - leftover;}
long[][] array = new long[firstIndex][secondIndex];
//loop through array
outerloop:
for(int i =0;i <firstIndex; i++)
{
for(int z = 0; z<secondIndex; z++)
{
System.out.println("do work with number here: " + array[i][z]);
if(z==(secondIndex-1))
{
z=0;
continue outerloop;
}
}
}
}
You might get a java.lang.OutOfMemoryError:, which can be resolved by reading this article https://plumbr.eu/outofmemoryerror/java-heap-space.
As others have indicated,
array[(int) index++] = j; // You use index and then increment it
System.out.print(" " + array[(int) --index]); // You decrement the index here
That's why index will always be 0 when you print it.
Personally, I don't like mixing brackets with increment operators for the precise reason you're seeing here - it tends to be confusing and it lends itself to subtle (and not-so-subtle) bugs and off-by-one errors. In fact, I really don't like mixing them with any other syntax (with the exception of for loops) as it can quickly become very unclear. For example, if you had done something like
index++;
array[(int)index] = j;
index--;
System.out.print(" " + array[(int)index]);
the problem would've been obvious immediately.
In general, it's a bad idea to sacrifice clarity for brevity.
Also, just to review how the operators in question are working:
index++ - use the value and then increment it
index-- - use the value and then decrement it
++index - increment the value and then use it
--index - decrement the value and then use it.
Here's a C# code sample I put together (Java's behavior will be identical) to illustrate this:
int i = 0;
Trace.TraceInformation((i++).ToString()); // Prints 0
Trace.TraceInformation(i.ToString()); // Prints 1
Trace.TraceInformation((--i).ToString()); // Prints 0
Trace.TraceInformation((i--).ToString()); // Prints 0
Trace.TraceInformation(i.ToString()); // Prints -1
I'd encourage you to trace/step through this to convince yourself that that's the case and to understand exactly why the value is what it is at every point.
Either way, this syntax can be very confusing if overused.

Subtracting a variable in a loop in Java

I'm trying to calculate how many rounds can a player play lotto and joker games with a fixed amount of money.
public static void example () {
int money = 200;
int lottoCost = 4;
int jokerCost = 3;
int costTogether = lottoCost+jokerCost;
int rounds = 0;
for (int i = money; i <= 0; rounds++) {
money = money-costTogether;
}
System.out.println("With " + money + " euros, you can play "
+ rounds + " rounds.");
System.out.println("");
}
That code currently prints the text "With 200 euros, you can play 0 rounds."
So it doesn't add a +1 to the rounds variable. What am I doing wrong?
In general, it is good to use the same variable in the 3 parts of the for. Note that the loop initialization part (the first one int i = money) is only run once, and you don't modify i during the loop. Furthermore, the condition is false from the beginning (200 < 0) so the loop is not even run once
I think what you are looking for is a simple int division, just replace your for block with this :
rounds = money / costTogether;
Your stopping condition is wrong, so the loop is never exectued. You should use >= instead. Also, you never change nor use i.
Here is a corrected version, using currMoney instead of i to be more meaningful.
int rounds = 0;
for (int currMoney = money; currMoney >= costTogether; currMoney -= costTogether) {
rounds++;
}
But obviously here, you only need a simple division as #Fredszaq pointed out in his answer:
int rounds = money / costTogether;
This condition i <= 0 is never true and probably dont get incremented
i guess its a typo ,
Greater and Lessthan you need to be aware as they change context .
Your for-loop is not defined correctly. i starts at money = 200. You want to repeat the loop as long as i <= 0. So you require i starting at 200 while not being larger than 0. That's why your loop isn't executed at all.
Instead prefer a while loop for your case. It is more readable:
while (money >= costTogether) {
money = money - costTogether;
rounds++;
}
If you want to use a for loop, you can declare it like that:
for (int i = money; i >= costTogether; i -= costTogether) {
rounds++;
}
You're only incrementing rounds, in a roundabout way, when the loop runs.
The loop runs while i <= 0 - i starts equal to money, which equals 200, so the loop never runs and the rounds value is not incremented.
You're also not changing i in the loop - I suspect you'd rather want while i >= 0 and decrement i in the loop?
for (int i = money; i >= 0; rounds++) {
money = money-costTogether;
i--;
}

Java calculating average of numbers from another file

public void computeAverage(String [] names, int [] scores, char [] grades){
int av = 0;
for (int i = 0; i < names.length; i++)
av = (scores[i]++ / 26);
System.out.print(av);
}
Hey guys,
Above is my code to read a list of test scores and compute their average. There are 26 test scores. I am having trouble, Please help!
Thanks
The problem here is that you keep writing over the av variable during each iteration of the loop. Also, it looks like you don't needs the names and grades arrays as parameters, as you're not using them. This should work better:
public void computeAverage(int [] scores)
{
double average = 0;
for (int i = 0; i < scores.length; i++)
{
average += scores[i];
}
average /= scores.length;
System.out.print(average);
}
Let's break this down:
You need to loop through your entires scores array and sum each score
to a running total
You need to then divide by total number of scores. As #cliff.meyers
pointed out, that is the definition of an average
As a side note, you are looping against name.length, but indexing
into scores. That is bad.
You are dividing by a hard coded constant. That is also bad.
You don't need names or grades in the function to calculate averages.
Try adding them all first, then dividing by the total number. That's how you calculate an average...
You need to add the contributions to the running tally:
av += (scores[i] / 26.0);
Perhaps even better to divide by names.length, and even better to leave the division to the end. Finally, be careful with integer division, which might not do what you think it does.
public static int computAverage(int[] scores)
{
long sum = 0;
for(int i : scores)
sum += i;
return sum / scores.length;
}

Categories

Resources