Why A Variable's Value Changes - java

I do not understand why the value of smallCountLoopCount changes from 0 to 1 in the code provided. I expect it to remain at 0. I use IntelliJ IDEA for testing. I have two statements to audit the values. Each are:
System.out.println("SMALL LOOP COUNT = " + smallCountLoopCount);
The first prints 0 and the second prints 1. What do I need to change to have the second one print 0?
I've tried working the () brackets to try and ensure that the math flows correctly, doing the multiplication first and then the addition second. It looks like the addition piece is incrementing the variable instead of doing math with it??
while (bigCountLoopCount <= bigCount) {
//System.out.println(bigCountLoopCount + " " + smallCountLoopCount);
if ((bigCountLoopCount * 5) == goal) {
//System.out.println("THIS TRUE ACTIVATED");
return true;
}
System.out.println("SMALL LOOP COUNT = " + smallCountLoopCount);
if (((bigCountLoopCount * 5) + smallCountLoopCount) == goal)
{
System.out.println("SMALL LOOP COUNT = " + smallCountLoopCount);
System.out.println("THIS TRUE ACTIVATED by:");
System.out.println(bigCountLoopCount + " " + smallCountLoopCount + " " + goal);
return true;
}
smallCountLoopCount++;
bigCountLoopCount++;
}
Expected result:
SMALL LOOP COUNT = 0
SMALL LOOP COUNT = 0
Actual result:
SMALL LOOP COUNT = 0
SMALL LOOP COUNT = 1

You have at the bottom of your while loop:
smallCountLoopCount++;
This is not surrounded by any condition so will always be executed. It is hard to see what exactly you're trying to do without the full piece of code, but if you want smallCountLoopCount to remain at zero, remove the above such as follows:
//System.out.println(bigCountLoopCount + " " + smallCountLoopCount);
if ((bigCountLoopCount * 5) == goal) {
//System.out.println("THIS TRUE ACTIVATED");
return true;
}
System.out.println("SMALL LOOP COUNT = " + smallCountLoopCount);
if (((bigCountLoopCount * 5) + smallCountLoopCount) == goal)
{
System.out.println("SMALL LOOP COUNT = " + smallCountLoopCount);
System.out.println("THIS TRUE ACTIVATED by:");
System.out.println(bigCountLoopCount + " " + smallCountLoopCount + " " + goal);
return true;
}
// smallCountLoopCount++ was here - Anything in this area will be executed regardless
bigCountLoopCount++;
}

This is because you have smallCountLoopCount++; at the end of the loop body. And apparently it doesn't hit neither of the returns.
If you change to goal=0 and bigCount=0 then you will get your desired output.

Related

When my loop repeats, why isn't the random value assigned to a certain variable changing?

System.out.println("Composition Statistics for Families with Two Children: \n");
System.out.println("Total Number of Families: ");
FamilyNumber = Integer.parseInt(in.nextLine());
List<String> list = Arrays.asList(boy, girl);
while (RunCount < FamilyNumber) {
randNum = (int)(Math.random() * 1 + 0);
randNum2 = (int)(Math.random() * 1 + 0);
FirstGender = list.get(randNum);
SecondGender = list.get(randNum2);
GenderValues = FirstGender + SecondGender;
if (GenderValues == "BG" || GenderValues == "GB") {
BGCount++;
}
else if (GenderValues == "GG") {
GGCount ++;
}
else {
BBCount++;
}
RunCount++;
}
GGPercent = ((double)(GGCount/FamilyNumber)*(100));
BGPercent = ((double)(BGCount/FamilyNumber)*(100));
BBPercent = ((double)(BBCount/FamilyNumber)*(100));
System.out.println("Number of Families with: \n");
System.out.println("\tTwo Boys: " + BBCount + " Represents " + BBPercent + "%");
System.out.println("\tTwo Girls: " + GGCount + " Represents " + GGPercent + "%");
System.out.println("\tOne Boy and One Girl: " + BGCount + " Represents " + BGPercent + "%");
This is the segment of code the issue is in. I already initialized all the variables and imported everything necessary. The problem is, whenever I run the program, I get this output:
Composition Statistics for Families with Two Children:
Total Number of Families:
15
Number of Families with:
Two Boys: 15 Represents 100.0%
Two Girls: 0 Represents 0.0%
One Boy and One Girl: 0 Represents 0.0%
The output is always two boys make up all the families. I'm assuming that the issue is with randNum and randNum2 variables, but I'm really not sure. I have no idea what to do so any input on where I'm going wrong is greatly appreciated.
Math.random returns a number between 0 and 1.
So when cast to an int it will be always 0.
Select a scaling factor and multiply the result (lets say 5)
and then the result will an int in the range 0-4

How to optimally distribute multiset into submultisets with a given sum

There is a sorted multi set of N integers where N<26, for example:
[1x4,2,5x2,6x2,15,55]
And some sum - for example 10. I would like to get maximum number of sub multi sets from above set that are at least equal to given sum. For example:
[1x3 + 2 + 5] = 10 - first sub multi set
[5 + 6] = 11 - second multi set
[15] - third multi set
[55] - fourth multi set
1,6 - leftovers.
(but as you can see this is not the only answer).
What is the best way to approach this problem? I'm trying to solve this problem in java but any solution with explanation would be appreciated.
Edit:
Currently I am trying below approach:
Create single element multi sets that are higher or equal too sum. Remove them from original set.
Find 2 element sub multi sets that are exactly equal to sum. Remove them from original set <- I'm at this point
And now I do not know how to progress or is my approach correct.
The question is in which point should I start accepting sub multi sets that are higher than sum and how to check if this wont cause loss of some multi sets that would be possible to create otherwise?
For now I have something like this:
private static String findAndRemoveMultisetsEqualTo(SortedMultiset<Integer> numbers, int searchForSum) {
String answer = "";
if (numbers.lastEntry().getElement() >= searchForSum) {
answer += "\nSet of " + searchForSum + " [" + numbers.lastEntry().getElement() + "]";
numbers.remove(numbers.lastEntry().getElement());
answer += " => " + String.valueOf(numbers);
return answer;
} else {
answer += findAndRemoveExactPairSumInMultiSet(numbers, searchForSum);
}
return answer;
}
private static String findAndRemoveExactPairSumInMultiSet(SortedMultiset<Integer> numbers, final int searchForSum) {
String answer = "";
List<Integer> tempList = numbers.stream().filter(number -> number <= (searchForSum / 2)).collect(Collectors.toList());
for (Integer number : tempList) {
if (numbers.contains(searchForSum - number) && (!number.equals(searchForSum - number))) {
answer += "\nSet of " + searchForSum + " [" + number + "," + (searchForSum-number) + "]";
numbers.remove(number);
numbers.remove(searchForSum - number);
answer += " => " + String.valueOf(numbers);
} else if (number.equals(searchForSum - number) && numbers.contains(number) && numbers.count(number) > 1) {
answer += "\nSet of " + searchForSum + " [" + number + "," + number + "]";
numbers.remove(number, 2);
answer += " => " + String.valueOf(numbers);
}
}
return answer;
}

How would I pass a variable through to a class, then back out to the class it was defined in with a different value?

I'm coding a "Nim" program for one of my classes inwhich a random number of rocks is generated, then the player and computer take turns removing 1-3 rocks from the pile. The player to remove the last rock loses.
However, no matter what the code generated for the computer inside the method, it would always return 0, and as such say the computer removed 0 rocks from the pile.
(It also may help to know that these are two separate files.)
//code code code...
System.out.println("You take " + playertake + " stones. There are " + rockCount + " left");
int computerTake = 0;
nimMethods.computerTake(computerTake);
rockCount = rockCount - computerTake;
System.out.println("The computer takes " + computerTake + " stones. There are " + rockCount + " left");
Here is my methods file :
public class nimMethods
{
static int computerTake(int y)
{
y = (int)(Math.random()*((1 - 1) + 3 + 1)); //randomly generating a value between 1-3
return(y);
}
}
I have a strong belief that this a logic error, and is coming from my lack of knowledge on methods. But people don't seem to be asking this question where I look.
Could someone give me a hand? And also explain your answer, i'd like to learn.
Thanks!
You should do:
computerTake = nimMethods.computerTake(computerTake);
The value of computerTake is not being changed in your code, so it stays 0 as initialized.
Not sure why your computerTake() method takes a parameter though.
That makes the code as follows:
System.out.println("You take " + playertake + " stones. There are " + rockCount + " left");
int computerTake = 0;
computerTake = nimMethods.computerTake();
rockCount = rockCount - computerTake;
System.out.println("The computer takes " + computerTake + " stones. There are " + rockCount + " left");
and
public class nimMethods
{
static int computerTake()
{
int y = (int)(Math.random()*((1 - 1) + 3 + 1)); //randomly generating a value between 1-3
return(y);
}
}
This is because Java is Pass by Value: The method parameter values are copied to another variable and then the copied object is passed, that’s why it’s called pass by value.
So you cannot see "changed" value of y oustide your computerTake method because the value of y was copied.
To fix it you can just replace the value of computerTake with your method result which you've returned
computerTake = nimMethods.computerTake(computerTake);

Java issue with updating a unique variable, Simulation 1 line 1 queue

I'm having a problem with a variable not updating when its supposed to. I also am not sure where to update this variable as it does not fit into any of the if statement tests in my code. YOU MUST UNDERSTAND, that all I need fixed is where the variable peopleCompleted gets updated when the first person to enter is done. In my code you'll see where this first person is arriving, taking his place as the curServed and then being printed without being added to the queue holding everyone else who is in line. You'll notice that curServed gets changed in the serviceComplete() because it handles everyone else IN THE QUEUE. Below is my code and sameple output that is incorrect because of peopleCompleted not being updated for that first person. Basically, I really need help with knowing where to update his completion in the first place. This is a Simulation of a One Line One Queue. I am a beginner/student
CODE
public boolean arrival()
{
Customer myCust = new Customer(curTime);
if(curServed == null) // If no one being served
{
curServed = myCust; // myCust is served
peopleNoWait++;
return true;
}
else if(!q.isFull())
{
q.add(myCust);
peopleThatHadToWait++;
return true;
}
return false;
}
public Customer serviceComplete()
{
if(q.isEmpty())
{
curServed = null;
}
else
{
curServed = q.remove(); // Remove next from customer queue
peopleCompleted++;
sumOfWaitTime += getWaitTime();
}
return curServed;
}
THESE BELOW HANDLE THE SIMULATION ABOVE
private void doArrival()
{
boolean check = sim.arrival(); // Do an arrival
if(check == false)
System.out.println("Customer arrived but left immediately"
+ " because the line was full (too long) at time " +
sim.getTime() + ".");
else
System.out.println("A customer entered system at time " +
sim.getTime() + "." + " Number waiting in queue is "
+ sim.getNumWaiting() + ".");
}
private void doServiceComplete()
{
if(sim.notBeingServed() == true)
{
System.out.println("No customer is being served at the present time"
+ " of " + sim.getTime() + ".");
}
else
{
System.out.print("Customer " + sim.getCurCust().toString() +
" finished at time " + sim.getTime() + ". Number waiting" +
" is ");
System.out.println(sim.getNumWaiting() + ".");
}
sim.serviceComplete();
Methods that return the vals below
public int getNumWaiting()
{
int total = peopleThatHadToWait - peopleCompleted;
return total;
}
public int getTotalServed()
{
return peopleCompleted;
}
Sample output where error is:
Customer C1/T2 finished at time 7. Number waiting is 2. // Should be 1
Customer C2/T6 finished at time 7. Number waiting is 1. // Should be 0
Customer C3/T7 finished at time 13. Number waiting is 5. // 4
Customer C4/T7 finished at time 16. Number waiting is 4. // etc
Customer C5/T8 finished at time 16. Number waiting is 3.
Customer C6/T8 finished at time 17. Number waiting is 2.
Customer C7/T9 finished at time 17. Number waiting is 1.
The number of people served is 7. // Should be 8
The number of people served is 7. // Should be 8
COMMENTS:
These are the lines causing issue. The number waiting and the number of people
served are the ones that are incorrect. It is because of the the lack of the
peopleCompleted being updated with that first person after he is completed, which
according to your advice, is not done in serviceComplete()
I suspect it's because of this code block here.
private void doServiceComplete()
{
if(sim.notBeingServed() == true)
{
System.out.println("No customer is being served at the present time"
+ " of " + sim.getTime() + ".");
}
else
{
System.out.print("Customer " + sim.getCurCust().toString() +
" finished at time " + sim.getTime() + ". Number waiting" +
" is ");
System.out.println(sim.getNumWaiting() + ".");
}
sim.serviceComplete();
}
When you get to sim.getNumWaiting() your people waiting will be one less than you're expecting. sim.serviceComplete() has peopleCompleted++ which is performed AFTER you print your results. You should move this to the beginning of the method, or somewhere else logical, before sim.getNumWaiting() is called.
Example:
private void doServiceComplete()
{
sim.serviceComplete();
if(sim.notBeingServed() == true)
{
System.out.println("No customer is being served at the present time"
+ " of " + sim.getTime() + ".");
}
else
{
System.out.print("Customer " + sim.getCurCust().toString() +
" finished at time " + sim.getTime() + ". Number waiting" +
" is ");
System.out.println(sim.getNumWaiting() + ".");
}
}

Round Robin in Java

I am working on a round robin algorithm in Java, and I have a loop that is not working correctly. I believe it is a simple logic error that I am missing. The exec[] array holds execution times for processes in a cpu. I need the quantam to be subtracted from that time or the amount of time left if less than the quantam. Then I need it to check the next process. Each process should have one pass through until the execution time is 0. The sum makes sure that the statements keep running while there is any one process that needs to run. The sum is simply from adding all the array element times.
while (sum != 0) {
int show = i + 1;
if (exec[i] != 0 && exec[i] > quant) {
exec[i] = exec[i] - quant;
sum = sum - quant;
JOptionPane.showMessageDialog(null, "Process" + " " + show + " is at" + " " + exec[i]);
JOptionPane.showMessageDialog(null, "sum" + " " + " is " + sum);
if (i == irq - 1) {
i = 0;
} else {
i++;
}
}
if (exec[i] != 0 && exec[i] < quant) {
exec[i] = exec[i] - exec[i];
sum = sum - exec[i];
JOptionPane.showMessageDialog(null, "Process" + " " + show + " is at" + " " + exec[i]);
JOptionPane.showMessageDialog(null, "sum" + " " + " is " + sum);
if (i == irq - 1) {
i = 0;
} else {
i++;
}
}
}
Please let me know if there is a fix or if any more information is needed. Thanks!
exec[i]=exec[i]-exec[i];
sum=sum-exec[i];
Is same as
exec[i]=0;
sum=sum-0;
Also, you don't treat the case of exec[i]==quant
I am not sure, what you want to do. It sounds like "I want Multithreading to make my application faster" but within in Single-Core loop, you won't succeed.
If you want a CPU round robin, let the JVM (or the operating system) decide. Both are made for this:
Some kind of java pseudo-Code:
int threadPoolSize = Runtime.getRuntime().availableProcessors();
ExecutorService pool = Executors.newFixedThreadPool(threadPoolSize);
pool.execute(new ImplementationOfCallableOrRunnable());
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

Categories

Resources