for (int i = 0; i < k; i++)
{
for (int j= 0; j < n; j++)
{
cout << ".":
}
}
I am trying to find the big O of this function. I believe it is O(n*n) but can someone explain to why it is? And what would the worst case be?
It's O(n*k). The outer loop runs k times, the inner runs n times, thus together k*n times.
Related
I need help to check whether my ascending sorting code has correct time complexity measurement or not.
Here is my code
for (int i = 0; i < 4344; i++)
{
for (int j = i + 1; j < 4344; j++)
{
if (array_dist[index_arr[i]] > array_dist[index_arr[j]])
{
x = index_arr[i];
index_arr[i] = index_arr[j];
index_arr[j] = x;
}
}
}
We have two nested loops so N^2 and if statement with 3 operations, so N^2 + 3 then we got O(N^2).
I am not sure if O(N^2) is the correct time complexity for my code. I want to know if the if statement could change my answer?
What is the time complexity (big O) of this function ? and how to calculate it ?
I think it's O(N^3) but am not sure.
int DAA(int n){
int i, j, k, x = 0;
for(i=1; i <= n; i++){
for(j=1; j <= i*i; j++){
if(j % i == 0){
for(k=1; k <= j; k++){
x += 10;
}
}
}
}
return x;
}
The complexity is O(n^4)
But not because you blindly drop unused iteration.
it's because when you consider all instruction, O(n + n^3 + n^4) = O(n^4)
int DAA(int n){
int x = 0;
for(int i=1; i <= n; i++) // O(n)
for(int j=1; j <= i*i; j++) // O(1+2+...n^2) = O(n^3)
if(j % i == 0) // O(n^3) same as loop j
for(int k=1; k <= j; k++) // O(n^4), see below
x += 10; // O(n^4) same as loop k
return x;
}
Complexity of conditioned inner loop
the loop k only execute when j%i==0, i.e. {i, i*2, i*3 ... i*i}
so for the case the inner-most loop execute, the algorithm is effectively
int DAA(int n){
int x = 0;
for(int i=1; i <= n; i++) // O(n)
for(int t=1; t <= i; t++) // O(1+2+...+n) = O(n^2)
for(int k=1; k <= t*i; k++) // O(n^4)
x += 10;
return x;
}
Why simply drop unused iteration not work?
let's say it's now
int DAA(int n){
int x = 0;
for(int i=1; i <= n; i++) // O(n)
for(int j=1; j <= i*i; j++) // O(1+2+...+n^2) = O(n^3)
if(j == i)
for(int k=1; k <= j; k++)
x += 10; // oops! this only run O(n^2) time
return x;
}
// if(j==i*log(n)) also cause loop k becomes O((n^2)log(n))
// or, well, if(false) :P
Although the innermost instruction only run O(n^2) time. The program actually do if(j==i)(and j++, j<=i*i) O(n^3) time, which make the whole algorithm O(n^3)
Time complexity can be easier to compute if you get rid of do-nothing iterations. The middle loop does not do anything unless j is a multiple of i. So we could force j to be a multiple of i and eliminate the if statement, which makes the code easier to analyze.
int DAA(int n){
int x = 0;
for(int i=1; i <= n; i++){
for(int m=1; m <= i; m++){ // New variable to avoid the if statement
int j = m*i; // The values for which the inner loop executes
for(int k=1; k <= j; k++){
x += 10;
}
}
}
return x;
}
The outer loop iterates n times. O(n) so far.
The middle loop iterates 1 time, then 2 times, then... n times. One might recognize this setup from the O(n2) sorting algorithms. The loop executes n times, and the number of iterations increases to n, leading to O(n×n) complexity.
The inner loop is executed on the order of n×n times (the complexity of the middle loop). The number of iterations for each execution increases to n×n (the maximum value of j). Similar to how the middle loop multiplied its number of executions and largest number of iterations to get its complexity, the complexity of the inner loop – hence of the code as a whole – should become O(n4), but I'll leave the precise proof as an exercise.
The above does assume that the time complexity represents the number of times that x += 10; is executed. That is, it assumes that the main work of the innermost loop overwhelms the rest of the work. This is usually what is of interest, but there are some caveats.
The first caveat is that adding 10 is not overwhelming more work than incrementing. If the line x += 10; is not a convenient stand-in for "do work", then it might be that the time complexity should include all iterations, even those that do no work.
The second caveat is that the condition in the if statement is cheap relative to the innermost loop. In some cases, the conditional might be expensive, so the time complexity should include the number of times the if statement is executed. Eliminating the if statement does interfere with this.
If you happen to fall into one of these caveats, you'll need a count of what was omitted. The modified code omits i2−i iterations of the middle loop on each of its n executions. So the omitted iterations would contribute n times n2−n, or O(n3) towards the overall complexity.
Therefore, the complexity of the original code is O(n4 + n3), which is the same as O(n4).
What should be the time complexity of the following code?
I tried to think and come up with O(n2) but the output says it to be of O(n). Can someone please explain through code?
for(int i = 0; i < n; i++){
for(; i < n; i++){
cout << i << endl;
}
}
The complexity of your code is O(n).
Why?
Because, even though you have written two for loops, which probably made you thinking the complexity is O(n2), your code is actually one for loop like:
for (i = 0; i < n; i++){
std::cout << i << std::endl;
}
Once the inner for loop finishes, i is equal to n and therefore the condition of outer for loop i < n is no longer satisfied.
One point to be noted while using such for loops is that your using a single variable.
Irrespective of how many outer loops you add, your code will result in the same with the condition i<n prevailing in all. The innermost loop is the one which will run till i=n-1, the rest of which simply won't satisfy the condition.
for(int i=0; i<n; i++)
{ for(; i<n; i++)
{ for(; i<n; i++)
{ for(; i<n; i++) // and so on.
std::cout<<i<<"\n";
}
}
}
Providing a variant to this, if you were to observe one such case of O(n2) complexity, your condition would have been i<n*n:
for(int i=0; i<n; i++)
{ for(; i<n*n; i++)
std::cout<<i<<"\n";
}
Time complexity of your code is O(n) and not O(n^2) because when inner loop ends, at that time value of i has already reached to n . So outer loop cannot run any more.
for(int i = 0; i < 2; i++){
for(; i < 2; i++){
cout << i << endl;
}
//after loop run two times i has value 2.
//and outer loop cannot run anymore
}
How does the if-statement of this code affect the time complexity of this code?
Based off of this question: Runtime analysis, the for loop in the if statement would run n*n times. But in this code, j outpaces i so that once the second loop is run j = i^2. What does this make the time complexity of the third for loop then? I understand that the first for loop runs n times, the second runs n^2 times, and the third runs n^2 times for a certain amount of times when triggered. So the complexity would be given by n*n^2(xn^2) for which n is the number of times the if statement is true. The complexity is not simply O(n^6) because the if-statement is not true n times right?
int n;
int sum;
for (int i = 1; i < n; i++)
{
for (int j = 0; j < i*i; j++)
{
if (j % i == 0)
{
for (int k = 0; k < j; k++)
{
sum++;
}
}
}
}
The if condition will be true when j is a multiple of i; this happens i times as j goes from 0 to i * i, so the third for loop runs only i times. The overall complexity is O(n^4).
for (int i = 1; i < n; i++)
{
for (int j = 0; j < i*i; j++) // Runs O(n) times
{
if (j % i == 0) // Runs O(n) × O(n^2) = O(n^3) times
{
for (int k = 0; k < j; k++) // Runs O(n) × O(n) = O(n^2) times
{
sum++; // Runs O(n^2) × O(n^2) = O(n^4) times
}
}
}
}
The complexity is not simply O(n^6) because the if-statement is not true n times right?
No, it is not.
At worst, it is going to be O(n^5). It is less than that since j % i is equal to 0 only i times.
The first loop is run n times.
The second loop is run O(n^2) times.
The third loop is run at most O(n) times.
The worst combined complexity of the loop is going to be O(n) x O(n^2) x O(n), which is O(n^4).
I have been working on an assignment question for days and cannot seem to get the correct output (I've tried so many things!) The question is:
Write a program that uses two nested for loops and the modulus operator (%) to detect and print the prime numbers from 1 to 10,000.
I have been doing from 1 to 10 as a small test to ensure its working. I am getting 2,3,5,7,9 as my output, so I know something is wrong. When I increase the number from 10 to 20 it is printing 2 plus all odd numbers. I am including my code below. Thanks!!
int main() {
for (int i=2; i <=10; i++){
for (int j=2; j<=i; j++){
if (i%j==0 && j!=i) {
break;
}
else {
cout<< i <<endl;
break;
}
}
}
}
In addition to Sumit Jindal's answer inner for loop can be done by this way as well:
for(int j=2; j*j<=i ; j++)
If we think about every (x,y) ordered pair that satisfies x*y = i, maximum value of x can be square root of i.
The problem lies in the if-else branch. Your inner loop will be run exactly once because it will break out of the inner loop as a result of your if else branch.
When you first enter the inner loop the value of j is 2. Your condition will test if variable i is divisible by 2. If it is it breaks. Other wise (your else branch) will print the value of i and breaks out.
Hence printing odd numbers.
Break out of the inner loop and check whether j equals i in outer loop. You have to make j available for outer loop.
Your print statement is within the inner loop, and it should not be - it's only a prime if you run all the way through the inner loop without finding a divisor.
As a second point, you only need to check for divisors up to the square root of i, not all the way up to i.
You are breaking the inner loop after the first iteration itself, which is checking if the number(ie i) is different from j and is divisible by 2 or not (since j=2 for the first iteration)
I am getting 2,3,5,7,9 as my output
This is because every odd number fails the if and is printed in else condition
A minor correction in your code, adding a flag. Also you don't need to run the inner loop i times, infact only i/2 times is sufficient. This is simple mathematics, but will save significant number of CPU cycles (~5000 iterations lesser in your case)
#include <iostream>
int main()
{
int n = 10;
for(int i=2; i<=n; i++){
bool isPrime = true;
for(int j=2; j<=i/2; j++){
if(i!=j && i%j==0){
isPrime = false;
break;
}
}
if(isPrime)
std::cout << i << " ";
}
return 0;
}
Another version, if you don't mind output in reverse order.
int n = 10;
for (int i = n; i > 1; --i)
{
int factorCount = 0;
for (int j = 2; j <= n; ++j)
{
if (i % j == 0)
factorCount++;
if (factorCount > 1)
break;
}
if (factorCount == 1)
cout << i << endl;
}
int main() {
for (int i = 2; i <= 100; i++) {
for (int j = 2; j < i; j++) {
if (i%j == 0)
break;
if (j==i-1) // means has never run previous if blog
cout << i << endl;
}
}
return 0;
}