I'm writing a simple cpu scheduler simulator, currently im at Round Robin algorithm. At this little piece of code, my way of implementing it is this:
take the total sum of the burst time from user input for keeping track when
this block should finish. as long as the sum is greater then or equal to 0, keep executing.
now, the problem is that the sum becomes negative and the block stops executing before the processes' burst time become all 0. is there any way i can fix this?
for example, suppose in our case that our input is {9, 12, 1, 1, 4, 4},
the output for phase 1 after executing all processes with quantum 4 is:
(where first column is the original array and the second one the decremented by quantum's value)
sum: 31
phase nr: 1
9 7 not zero
12 10 not zero
1 0 check
1 0 check
4 2 not zero
4 2 not zero
phase nr: 2
7 5 not zero
10 8 not zero
0 0 check
0 0 check
2 0 check
2 0 check
at this stage sum becomes negative and stops printing other processes
this is the code ive been working so far. i dont know if this explanation is clear enough, i tried to be as clear and specific as i could.
note: all jobs has an arrival time of 0
int[] a = {9, 12, 1, 1, 4, 4};
int sum = 0;
//total sum of the a[]
for (int i = 0; i < a.length; i++)
{
sum += a[i];
}
System.out.printf("\nsum: %d\n\n", sum);
int counter = 1;
while(sum >= 0)
{
System.out.printf("\nphase nr: %d\n", counter);
for (int i = 0; i < a.length; i++)
{
//prints the original array
System.out.printf("%d ",a[i]);
int value = a[i]; //takes a value from a[] at index i
value -= 2; //decrement the value by quantum 2
a[i] = value; //put the value at the same index
if (a[i] < 0) //it checks if any element is less than 0, if yes replace it with 0
{
a[i] = 0;
}
/**
*prints the array after subtracting 2 from each element
*in the original array and checks if there is any value
*equal to 0, if yes print "check" else "not zero"
*/
System.out.printf("%d \t%s",a[i], a[i]==0?"check":"not zero");
System.out.println();
}
/**
* decrements the sum based on the quantum
* multiplied by processes
* sum = sum -(quantum * numberOfProcesses)
*/
sum = sum - (4 * 6);
counter++;
}
The problem is in calculating your sum.
sum = sum - (4 * 6);
You subtract 24 in every iteration even if processes finish earlier(like in 1 quantum of time) or are already finished.
What you should subtract from sum in every iteration is the total time spent on actual processing. So if process is done (a[i] == 0) you don't proceed, and if the a[i] < 4 you subtract that value. Only when a[i] >=4 you should subtract 4 quanta.
If you want to spend 4 quanta of time for every process regardless of its real needs and if it's done or not then you calculate your sum wrong and it's not really Round Robin.
while(sum >= 0)
{
System.out.printf("\nphase nr: %d\n", counter);
for (int i = 0; i < a.length; i++)
{
//prints the original array
System.out.printf("%d ",a[i]);
int value = a[i]; //takes a value from a[] at index i
if(a[i] == 0) { continue;} // skip process if it's done
else if(a[i]<=4) { sum -=a[i]; a[i]=0;} // if process is less than one quantum then it's done and sum is decreased by time needed
else { sum -=4; a[i] -=4} // otherwise process needs more than one quantum so it uses up all 4
/**
*prints the array after subtracting 2 from each element
*in the original array and checks if there is any value
*equal to 0, if yes print "check" else "not zero"
*/
System.out.printf("%d \t%s",a[i], a[i]==0?"check":"not zero");
System.out.println();
}
// this part was completely unnecessary so it was removed to for loop above
counter++;
}
I'm not sure too fully understand your algorithm, but the computation of the sum is not correct. You should define some function that will sum the actual values in the array a[] instead of having some wrong constant computation (you use 4 for quantum instead of 2) and ignore the fact that some a's are not decremented once they are set to 0.
You can define something like :
public static int totalBurstTime(int[] bursts) {
int total = 0;
for (int b : bursts) {
total += b;
}
return total;
}
and call it to initialise the sum before the while loop, and then at the end of each loop.
Also, you should use some constants instead of magic numbers, eg
static final int QUANTUM = 2;
and use it everywhere you need...
Related
There are N bulbs from 1 to N in a series circuit. An array denotes the bulb number from 0 to (N-1). Initially all bulbs are turned off and are switched on from index 0 of array. We need to count the number of instances for which the bulbs are switched on in series circuit.
For example :
A=[2,1,3,5,4] should return 3
Explanation :-
Instant Bulb number on All bulbs in series switched on
0 2 false
1 1,2 true
2 1,2,3 true
3 1,2,3,5 false
4 1,2,3,4,5 true
So there are 3 instances where the bulbs are switched on. Count is 3.
My approach
Iterate over the indexes of array
Take slice of array from 0 to index
Sort the array
Check whether array has all bulbs from 0 to index-1 switched on
Count the number of instances.
My solution runs perfectly fine, but has a time complexity of O(n2). My solution is as follows
public int solution(int[] A) {
// write your code in Java SE 8
int counter = 0;
for (int i = 0; i < A.length; i++) {
int[] intermediate = Arrays.copyOfRange(A, 0, i);
Arrays.sort(intermediate);
if(checkIfOrdered(intermediate))
counter++;
}
return counter;
}
private static boolean checkIfOrdered(int[] intermediate) {
boolean flag = true;
for (int i = 0; i < intermediate.length; i++) {
if(intermediate[i] != (i +1) ){
flag = false;
break;
}
}
return flag;
}
Can somebody please point out as to what can be done to improve the performance of my code ?
Any pointers will be highly helpful !!!
With these problems, you can sometimes remove some of the loops needed by calculating the answer differently.
In your example, the only information that seems to be needed at each instant is the number of bulbs on, and the largest bulb number found so far.
For example:
At instant 1, there are 2 bulbs on and 2 is the largest number.
At instant 3, there are 3 bulbs on and 3 is the largest number.
At instant 4, there are 5 bulbs on and 5 is the largest number.
The answer is the number of times the largest number is equal to the number of bulbs on.
#fgb has indicated a simple criterion: will be true when max == count.
Then, you only have to calculate the maximum and count values.
public static int solution(int [] xs) {
int max = xs[0];
int count = 0;
int trues = 0;
for(int x: xs) {
max = Math.max(max, x);
count = count + 1;
if(max == count)
trues = trues + 1;
}
return trues;
}
I have N numbers, and a range, over which I have to permute the numbers.
For example, if I had 3 numbers and a range of 1-2, I would loop over 1 1 1, 1 1 2, 1 2 1, etc.
Preferably, but not necessarily, how could I do this without recursion?
For general ideas, nested loops don't allow for an arbitrary number of numbers, and recursion is undesireable due to high depth (3 numbers over 1-10 would be over 1,000 calls to the section of code using those numbers)
One way to do this, is to loop with one iteration per permuation, and use the loop variable to calculate the values that a permuation is made off. Consider that the size of the range can be used as a modulo argument to "chop off" a value (digit) that will be one of the values (digits) in the result. Then if you divide the loop variable (well, a copy of it) by the range size, you repeat the above operation to extract another value, ...etc.
Obviously this will only work if the number of results does not exceed the capacity of the int type, or whatever type you use for the loop variable.
So here is how that looks:
int [][] getResults(int numPositions, int low, int high) {
int numValues = high - low + 1;
int numResults = (int) Math.pow(numValues, numPositions);
int results[][] = new int [numResults][numPositions];
for (int i = 0; i < numResults; i++) {
int result[] = results[i];
int n = i;
for (int j = numPositions-1; j >= 0; j--) {
result[j] = low + n % numValues;
n /= numValues;
}
}
return results;
}
The example you gave in the question would be generated with this call:
int results[][] = getResults(3, 1, 2);
The results are then:
1 1 1
1 1 2
1 2 1
1 2 2
2 1 1
2 1 2
2 2 1
2 2 2
I am working on an exercise where a small piece of code based on a for-loop is converted to preform the same operation with a while loop. The conversion is wrong by purpose, and looks like this:
int sum = 0;
for (int i = 0; i < 4; i++) {
if (i % 3 == 0) continue;
sum += i;
}
System.out.println(sum); // prints 3
This is converted into:
int i = 0, sum = 0;
while (i < 4) {
if (i % 3 == 0) continue;
sum += i;
i++;
}
System.out.println(sum); // will not print
In the exercise, I am asked to explain why the conversion is wrong and then fix it. My thoughts are:
With the initial value of i = 0, this will trigger continue instantly after entering the will loop, since (0 % 3 == 0) will make the if-statement true. As long as the initial value is 0, this will execute the loop, for so to skip it an endless amount of times. I tried changing the initial value of i = 1, but noe sum is printed. Then I tried to increment i before executing the if-statement, and the program now prints the sum 7. The question here is; why won't the program print if i incremented after the if statement, even if the initial value of i = 1 suggests (in my head) that program should run properly?
I made a table for each program to compare the summing.
The for-loop version:
i = 0, sum += i not preformed (continue), i++
i = 1, sum = 1, i++
i = 2, sum = 3, i++
i = 3, sum += i not preformed (continue), i++
i = 4, i < 4 false, loop stopped
The while-loop version:
i = 0, i++, sum = 1
i = 1, i++, sum = 3
i = 2, i++, sum += i not preformed (continue)
i = 3, i++, sum = 7
i = 4, i < 4 false, loop stopped
In the while-loop, sum += i is preformed once more than in the for-loop. Is this the right way to convert the for-loop into a while-loop?
int i = 0, sum = 0;
while (i < 3) {
i++;
if (i % 3 == 0) continue;
sum += i;
}
System.out.println(sum);
Your 1 is focussing on it being the initial value, but that's not the point. The point is that i is never incremented when i % 3 == 0 is true, not that 0 is the initial value. So the while loop loops forever.
Your 2 doesn't make any sense: The while version will loop forever, never summing anything.
Is this the right way to convert the for-loop into a while-loop?
No, you're incrementing i at the wrong time.
Think bout how a for loop works:
Initialization - First it sets the variables to the values in the first expression.
Test - Then it tests the values using the second expression.
Execute - If the value is true, it executes the loop body.
Increment - When the loop body is complete, it executes the third (increment) expression. Note that this is after the loop body.
Make your while loop do what the for loop is doing. (I'm intentionally not doing that for you; this is a learning exercise. I'll note that the best way to convert that for loop will not use continue, however. "Best," of course, is subjective.)
In the exercise, I am asked to explain why the conversion is wrong and then fix it
The conversion is wrong simply because when you will reach a i value that modulo 3 equals 0 (the first iteration in that case), you will skip to the next iteration and re-validate. However, since you skipped directly without incrementing i , you will re-validate the same condition and re-validate ad-infinitum.
You could fix it easily by getting rid of the continue and negating the condition :
while (i < 4) {
if (i % 3 != 0)
sum += i;
i++;
}
The for-loop given by the question if converted to plain English, it means sum up from 0 to 3 and exclude all multiples of 3. (0+1+2=3)
for (int i = 0; i < 4; i++) {
if (i % 3 == 0) continue;
sum += i;
}
So now, we ask ourselves, how do we sum up 0 to x and exclude all multiples of 3 using a while-loop. We will do this without looking at the original for-loop. (Sometimes it is easier to do it this way since we already know the intention of the for-loop)
To sum up a number from 0 to 3:
int i = 0;
while(i < 4){
sum += i;
i++;
}
To sum a number from 0 to 3, excluding multiples of 3:
int i = 0;
while(i < 4){
if(i % 3 != 0)
sum += i;
i++;
}
To sum a number from 0 to 3, excluding multiples of 3 (using continue):
int i = 0;
while(i < 4){
if(i % 3 == 0){
i++; //Remember to increase i before continue
continue;
}
else
sum += i;
i++;
}
Since after the continue, all statements below it will be skipped, you have to remember to do an increment i++ before calling continue. There will be another i++ since you branch out into 2 conditions now.
According to the while loop logic, increment of variable i is conditional where as for for-loop it is unconditional. To make the increment logic uniform, you should increment in both cases.
I think the proper converting would be -
int i = 0, sum = 0;
while (i < 4) {
if (i % 3 == 0) {i++;continue;}
sum += i;
i++;
}
System.out.println(sum);
Normally the increment would be on the last line of a while loop. However, in this "disaster waiting to happen" code, there is a condition to skip to the end of the while block without incrementing i. If you are relying on i to increment, make sure it is always executed on any iteration. And also, at the end, because you want it to iterate the first time.
while (i < 4) {
if (i % 3 == 0) {
// skip!
} else {
sum += i;
}
i++;
}
I understand how mostly everything works in a loop in Java but I came to a realization that I am failing to understand one thing which is The Order a Loop Operates.
Basically I am failing to understand this because of this simple but boggling piece of code that was displayed in my class, the code is displayed below.
public class Test {
public static void main (String[] args) {
int sum = 0;
for (int k = 1; k < 10; k += 2)
{
sum += k;
System.out.print(sum + " ");
}
}
}
The output the program puts out is 1 4 9 16 25
Now I understand how it repeats and spits out the numbers but how does it go about even creating 1. Now you can say it created 1 by taking k and adding it to sum but shouldn't k be equaling 3?
It goes k = 1; This sets k equal to 1. k < 10; Checks if k is less than 10. Then the question is when k += 2; Shouldn't k now equal to 3 but instead sum is now somehow equal to 1 after this operation occurred of adding 2 to 1, 2 + 1 = 3 but 3 + 0 = 1? How does this even go about.
My rationalizing for this is that any program I thought was to interpret code line by line or uniformly and not jumping around.
Overall my question is, how is sum equal to 1 when k is actually equal to 3.
The sections of the for loop are run at different times.
The first section is run once at the start to initialize the variables.
The second is run each time around the loop at the START of the loop to say whether to exit or not.
The final section is run each time around the loop at the END of the loop.
All sections are optional and can just be left blank if you want.
You can also depict a for loop as a while loop:
for (A;B;C) {
D;
}
is the same as:
A;
while (B) {
D;
C;
}
Let's step through your code:
We setup an int with initial value of 0 and assign it to sum.
We setup a for loop, setting int k = 1, and we will loop while k is less than 10, and after each iteration, 2 will be added to k.
So, the first iteration, k = 1. sum currently equals 0, so sum += k is actually 0 = 0 + 1 = 1. There's the 1 you are getting.
For the second iteration, k = 3. sum currently equals 1, so sum += k is actually 1 = 1 + 3 which is 4. There's the 4 that is showing up.
Repeat this for the rest of the loop!
In the first iteration of the loop, k=1. The k+=2 is only run at the beginning of the next iteration of the loop. The loop variable update condition (the last part of the for loop - i.e. the k+=2 part) never runs on the first iteration but does run on every other one, at the start. Therefore what you have is:
Iteration 1:
k=1
sum = 0 + 1; //so sum = 1
Iteration 2:
k=1+2 // so k=3
sum = 1 + 3 // so sum = 4
Iteration 3:
k=3+2 //k=5
sum = 4 + 5 //sum=9
etc...
It goes like this:
Initialize (k = 1)
Check condition (k < 10) (stop if false)
Run the code in the loop (sum += k and print)
Increment (k += 2)
Repeat from step 2
Following this logic, you get that 1 is printed first.
The last condition, k += 2 occurs after the first iteration of the loop.
So it's
k = 1, sum = 1
k = 3, sum = 4
k = 5, sum = 9
k = 7, sum = 16
k = 9, sum = 25
k is only incremented after the loop iteration. In general for any loop the values are updated after a loop iteration so k goes 1,3,5,7,9 and so the sum is correct.
Oh believe I had same problem. And you have to understand this quickly because when you are going to start doing bubble sort it will confuse you even more.
The thing you need to understand is that, its that it doesnt actually add +2 to 'k' until its done reading whats inside your 'for loop'
So this is how it starts, its starts with what you set 'k' for which is 1.
k = 1 is it less than 10? Yes, then do whats in the 'for loop' . Sum at first was initiated to 0. then in the first loop we add the value of k to whatever sum already has. So
sum = 0, k = 1. Therefore 0 +1 = 1. then next line ouput the value of sum with space. AND here is the IMPORTANT PART, it has now reach the end of the loop. So now it will add +2 to the value that k already has.
So k = 1 + 2 = 3. And now we start the second loop.
k=3, is less than 10? yes, ok do whats in for loop. add k to whatever value that sum already has. Sum is = 1 right ? and k is now equal to 3 right? So 3 + 1 = 4. And it display sum with a space and it has reach the end of the for loop so it add +2 to k that already has 3 in it which will equal to 5. and the loop continues.
oouff hope that helps! So remember it adds +2 at the end of the loop. Sorry if theres some typos typing from my samsung kinda annoying a bit cuz i have japanese keyboard...
Good luck!
has to
Let's break up your code. The keyword for just means loop. It will start # 1 and continue as long as k is less than 10. It will also increase by k+=2. To translate, it means k = k +2
Inside the loop sum = sum + k. It will then print the value that sum has plus a space.
k = 1, sum = 1
k = 3, sum = 4
k = 5, sum = 9
k = 7, sum = 16
k = 9, sum = 25
and keep repeating. Let me know if you still have trouble grasping this concept
I am working through a section of a text on determining complexity of nested loops using recurrence relations. In this particular example I am trying to determine how many times the count variable will be incremented as a function of n.
This is the loop I am analyzing:
for (int i = 1; i <= n; i++) {
int j = n;
while (j > 0) {
count++;
j = j / 2;
}
}
I think I understand that the first line would equate simply to n since it only executes for each value of n but it's the rest of it that I'm having trouble with. I think the answer would be something like n(n/2) except that this example is using integer division so I'm not sure how to represent that mathematically.
I've run through the loop by hand a few times on paper so I know that the count variable should equal 1, 4, 6, 12, 15, and 18 for n values of 1-6. I just can't seem to come up with the formula... Any help would be greatly appreciated!
The loop executes for n in the range [1, n]. It divides by 2 each time for the j variable, which is set to n, so the number of time the inner loop executes is floor(l2(n)) + 1, where l2 is the binary log function. Add up all such values from 1 to n (multiply by n).
The inner j loop adds the location of the first set bit to count.
Each divide by 2 is the same as a right shift until all the bits are zero.
So, 2 would be 10 in binary, and have a value of 2 for the inner loop.
4 would be 100 in binary, and have a value of 3 for the inner loop.
The outer loop seems to just multiply the location of the first set bit by the number itself.
Here is an example with n = 13.
13 in binary is 1101, so the first set bit is at location 4.
4 * 13 = 52. 52 is the final answer.
for (int i = 1; i <= n; i++) {
This loop at the top goes through the loop n times.
int j = n;
while (j > 0) {
count++;
j = j / 2;
}
This loop here goes through the loop log(n) times, noting that it is a base 2 log since you are dividing by 2 each time.
Hence, the total number of counts is n * ceiling(log(n))