int k;
for (int i = 1; i < 10; i++) {
k = 2*i-1;
System.out.print(k+" ");
}
How would I write the above statement with the computation done in the header? I can't seem to figure out the syntax..
So I'm going to answer your question and suggest one minor improvement which moves k into the proper scope of the loop:
for(int i = 1, k = 2*i - 1; i < 10; i++, k = 2*i - 1) {
System.out.println(k+" ");
}
I'm also tending to agree with the comments. You probably should just leave the computation of k inside the loop body for readability's sake. You can still put the declaration of k in the header if k is not needed outside of the scope of the loop.
Related
I am learning how to do time complexity in school and the professor uploaded some examples. For the first example below, the answer is supposed to be O(n^3) but I do not understand how.
public static int fragment1 (int n)
{
int sum = 0;
for (int i = 1; i <= n*n; i++)
for (int j = 0; j*j < i; j++) sum++;
return sum;
} // end fragment1
When I attempt the problem I look at the first for loop and see that it runs n^2 times, then the inner for loop is also n^2. When added up I get O(n^4).
public static int fragment5 (int n)
{
int sum = 0;
for(int i=0; i < n*n*n; i++)
{
if(i%(n*n) == 0) {
for(int j=i*i; j > 0; j--)
sum++;
} // if
else
{
for(int k=0; k < i: k++)
sum++;
} // else
} // outer loop
}
For the problem above, the answer should be O(n^7). When I attempted it I got: first for loop runs n^3 times, inner for loop n^3*n^3 = n^6, and the for loop inside the else statement I get n with my final answer being O(n^10). Can someone give me tips on the above problem? I feel clueless when it comes to this one and I have been getting the other problems right so far.
One of the basic assumptions when calculating BigO is to drop non dominant terms.
Using the first example,
Outer Loop has order O(n^2)
Inner Loop has order O(n^3)
The inner loop independently runs for 'n' times but because it is nested, it will run for 'n * (n^2)
'
So, the BigO is of the form O((n^2) + (n^3)) which would suffice to O(n^3).
You can try using the same technique for the second problem.
If you still have some confusion, have a look at the following video:
Big O Notation
1.
for(i = 0; i < 3; i++){
for(j = 0; j < 10; j++){
print i+j;
}
}
I would assume Big O would be 30 since the most amount of times would be 3*10.
2.
for(i = 0; i < n; i++){
for(j = 0; j < m; j++){
print i+j;
}
}
Would be O be n*m?
3.
for(i = 0; i < n; i++){
for(j = 0; j < m; j++){
for(int k = 1; k < 1000; k *= 2){
print i+j+k;
}
}
}
n * m * log base 2 (1000) The Big O is in nlog(n) time
4.
for(i = 0; i < n - 10; i++){
for(j = 0; j < m/2; j++){
print i+j;
}
}
5.
for(i = 0; i < n; i++){
print i;
}
//n and m are some integers
for(j = 1; j < m; j *= 2){
print j;
}
Can someone give me a hand with this if you know Big O. I am looking at these and at a loss. I hope I am posting this in the right location, I find these problems difficult. I appreciate any help.
I think it's important just to point out that Big O notation is all about functions that, given an arbitrary constant, will be considered upper bounds at some point.
O(1)
This is because each loop iterates in a constant amount of time. We would refer to this as O(1) instead of O(30) because the function which is the upper bound is 1 with an arbitrary constant >=30.
O(n*m)
Simply because we have to loop through m iterations n times.
O(n*m)
This is the same as the previous one, only we're throwing in another loop in the middle. Now you can notice that this loop, similar to the first problem, is just a constant time. Therefore, you don't even need to really spend time figuring out how often it loops since it will always be constant - it is O(1) and would be interpreted as O(n*m*1) which we can simply call O(n*m)
O(n*m)
For the outer loop, don't get caught up on the .. - 10 and realize that we can just say that loop runs in O(n). We can ignore that .. - 10 for the same reason we ignored the exact values in the first problem; constants don't really matter. This same principle applies for the m/2 because you can think of m just being manipulated by a constant of 1/2. So we can just call this O(n*m).
T(n) = O(n) + O(lg m) => O(n + lg m)
So there are two components we have to look at here; the first loop and the second loop. The first loop is clearly O(n), so that's no problem. Now the second loop is a little tricky. Basically, you can notice that the iterator j is growing exponentially (notably power of 2's), therefore that loop will be running the inverse of exponentially (logarithmic). So this function runs in O(n + lg m).
Any constant factor can be ignored. O(30) is equal to O(1), which is what one would typically say for 1).
2) Just so.
3) in O(n*m*log_2(1000)), log_2(1000) is constant, so it's O(n*m).
4) O(n-10) is same as O(n). O(m/2) is same as O(m). Thus, O(n*m) again.
5) Trivially O(n).
6) O(log_2(m)).
I have the following code from a previous past paper:
int n = arr.length;
double min = 0;
int minLocation=0;
for(int i = 1; i <= n; i++) {
if( arr[i] < min ) {
min = arr[i];
}
minLocation = i;
}
System.out.print("The minimal value is arr[");
System.out.println(minLocation + "] = " + min);
I have to answer the following questions from the code:
(i) The line on which the error appears
(ii) What effect the error would have
(iii) How the error should be corrected.
You may assume arr[] is a non-empty array of double values that has been
properly declared and initialized.
I know there will be a runtime error at the line with the if statement which i'm still not sure how. As I am unable to correct it I can't see how I get the undesired results. I can see it's such a straight forward question and I am missing out something extremely obvious but I have been looking at it for a while and i'm completely missing it.
There are several mistakes in that code. Here a list of them including explanation of impact and how to fix them:
You are initialising min with 0
Effect: If your array e.g. only consists of {1.1, 2.2} your code would claim that 0 is the minimum, what obviously is wrong because there doesn't exist an index i that arr[i] == 0
Fix: double min = Double.MAX_VALUE;
Your for-loop starts at index 1 for (int i = 1; ...)
Effect: You are skipping arr[0]
Fix: for (int i = 0 ...)
Your loop iterates once to often because of the condition or ( ... ; <= n; ...)
Effect: You will encounter an AIOOBE (ArrayIndexOutOfBoundsException)
Fix: for ( ... ; i < n; ...)
Your are overwriting minLocation in every iteration of the loop
Effect: After the last iteration of the loop, minLocation will always be = n
Fix: Place minLocation = i; inside the if-statement.
Corrected version
int n = arr.length;
double min = Double.MAX_VALUE;
int minLocation = 0;
for(int i = 0; i < n; i++) {
if(arr[i] < min) {
min = arr[i];
minLocation = i;
}
}
I know there will be a runtime error at the line with the if statement
which i'm still not sure how
This runtime error will be IndexOutOfBoundsException. This error occur because array index is one less than array size.
Your loop should be like.
for(int i = 0; i < n; i++)
Did you intend your for() loop to start at index 1? By convention it starts at 0;
It should really be: for(int i=0;i
Your for loop needs to be:
for(int i = 0; i < n; i++)
Otherwise you will get an IndexOutOfBoundsException since you access the array outside of its range.
Also you should change your min value initialiaztion to:
double min = Double.MAX_VALUE;
Otherwise you will only find the minimum if your array only contains negative values.
There are logical errors in your program, if it is intended to find the minimal value and position of given array.
Initialize
double min = arr[0];
End for loop at
i < n
Include
minLocation = i;
as
if( arr[i] < min )
{
min = arr[i];
minLocation = i;
}
Java array indices start at 0. So the for loop should be for( int i = 0; i < n; i++ ).
The minimum is only computed if the the elements of the array are non-negative.
Suppose you want to loop from i=0 to i=n and j=0 to j=m and that m!=n. Is it possible to shorten the following two loops into one?
for(int i=0; i<=n; i++){}
for(int j=0; j<=m; j++){}
To something along
for(int i=0,j=0; i<=n, j<=m; i++, j++){}
In essence I want the loop to say "increment both i and j by one, stop incrementing i if i=n but keep incrementing j if m>n" or the other way around if n>m.
May seem trivial or stupid but I am curious.
Naively, we want to do something like:
for(int i = 0, j = 0; i <= n || j <= m; i = Math.min(n, i+1), j = Math.min(m, j+1))
...but this won't terminate, because the maximum value for i is n and the maximum value for j is m, and one of those will always be true.
The problem is much simpler if you're willing to let (for n < m) i finish at n+1, as we could write:
for(int i = 0, j = 0; i <= n || j <= m; i = Math.min(n+1, i+1), j = Math.min(m+1, j+1))
This is complicated only if you want to keep (for n < m) i = n while j finishes incrementing. The complexity is isolated to getting the loop to terminate at the right time, while still allowing j to finish incrementing.
To get the loop to terminate, we want to increment the larger number one step past its maximum, so that we hit the termination criteria. Since we know at least one of i <= n and j <= m will always be true, let's focus on making both always true, and change our termination criteria to
i <= n && j <= m
In the case where n < m, i will finish incrementing before j, and so we need to let j increment one past its effective maximum in order to violate i <= n && j <= m. A similar condition holds for n > m, but instead, we need to increment i one past n.
Notice, though, that if n == m, we can safely increment both one past their respective limits, and the termination criteria will hit at the same time. The loop below handles any positive input n or m and terminates correctly given your conditons, while allowing the lesser of n or m to become the maximum value for the respective iterator.
for(int i = 0, j = 0, nadj = n + (n >= m ? 1 : 0), madj = m + (m >= n ? 1 : 0)
i <= n && j <= m;
i = Math.min(nadj, i+1), j = Math.min(madj, j+1))
Worth noting, we compute nadj and madj in the first section to avoid recomputing them during every iteration.
Edit
for(int i=0,j=0; i+1<=n || j+1<=m; ){
if(i<n) i++;
if(j<m) j++;
// do stuff here
// keep in mind that i and j starts from 1
}
Fiddle: http://jsfiddle.net/nilgundag/4frCG/
Old Answer:
for(int i=0,j=0; i<=n || j<=m; ){
if(i<=n) i++;
if(j<=m) j++;
// do stuff here
// keep in mind that i and j starts from 1
}
You can use only one iterator i since you increment i and j by 1 every time.
for(int i=0; i<=n || i<=m;i++ ){
if(i<=n) //{do first loop job}
if(i<=m) //{do second loop job}
}
C++:
for (int i=0, j=0; j<=m || i<=n; i+=i<=n, j+=j<=m ){}
JAVA:
for (int i=0, j=0; j<=m || i<=n; i+=(i<=n)?1:0, j+=(j<=m)?1:0 ){}
Im revising for my SCJA exam at the minute and im confused by this question and answer. The question is what is the result of running and compiling the code.
public class Test{
public static void main(String args[]){
int counter = 0;
for(int i=0; i< 4; ++i){
for(int k=0; k< 4; ++k){
system.out.println("Hello - "+ ++counter);
if((k % 4) == 0)
break;
}
}
}
}
So the answer they give is "Hello-1" because 0 % 4 = 0
But my question is should k not be 1 because its been pre-incremented?
Thanks in advance!
A for loop has the following structure:
for (initialization; condition; update)
The update is executed after every execution of the loop.
Therefore the following two loops are identical:
for (int i = 0; i < 10; i++) {
and
for (int i = 0; i < 10; ++i) {
my question is should k not be 1 because its been pre-incremented?
The ++k happens at the end of the loop iteration, i.e. after the if statement.
It makes no difference whether it's ++k or k++; in either case the first value of k is zero.
So the answer they give is "Hello-1"
This is clearly incorrect, since counter is never incremented and stays at zero throughout the program.
k cannot be 1.
This is because when a for loop runs, it only updates after it has executed all the code within the loop. Since the loop breaks even before the first iteration is completed, k remains 0.