简体   繁体   中英

Times of code been executed in a nested for loop in Java

I am recently reading the book called Algorithms by Robert Sedgewick. I came across one piece of code while reading "Analysis of Algorithms". The code is as follow :

public static int count(int a[]) {
    int N = a.length;
    int cnt = 0;
    for (int i = 0; i < N; i++) {

        for (int j = i + 1; j < N; j++) {
            for (int k = j + 1; k < N; k++) {
                if (a[i] + a[j] + a[k] == 0) {  //here 
                    cnt++;
                }
            }
        }
    } 
    return cnt
}

What I want to know is how many times of the if -statement within the for -loop been executed. The answer provided by the book is N(N-1)(N-2)/6 . But I don't know why, could anyone explain.

You just need to evaluate the following sum:

在此处输入图片说明

You could do that by hand, but Wolfram Alpha is much better at that.

It is not hard to verify that

(N-1)(N-2) = N2 - 3N + 2

which shows the formula you gave.


For the manual analysis:

Start with the inner sum, which is easy:

在此处输入图片说明

Plugging this in the middle sum gives:

在此处输入图片说明

This sum would be easier to evaluate if the dummy variable started from 0 (rather than i+1 ), therefore we apply the dummy transformation p = j - i - 1 :

在此处输入图片说明

Finally, this must be plugged in the outer sum:

在此处输入图片说明

I've been having a play with this. It seems the question is as much one of Mathematics as it is of computing.

First thing's first. The actual contents of the if statement are a complete red herring as they are dependent on the contents of the array. I have used the first x natural numbers starting from 0 (effectively the index of the array) and as such the if statement never resolves to true.

To test the assertion that the if statement is accessed n(n-1)(n-2) times I have changed the code to the following:

public class Iteration {



public static void main(String[] args) {
    int[] a = {0,1,2,3,4};

    System.out.println(count(a));



}

public static int count(int a[]) {
    int N = a.length;
    int cnt = 0;
    int access = 0;

    for (int i = 0; i < N; i++) {

        for (int j = i + 1; j < N; j++) {
            for (int k = j + 1; k < N; k++) {

                access++;
                System.out.println(access + " " +a[i] + a[j] + a[k]);
                if (a[i] + a[j] + a[k] == 0 ) {  //here 
                    cnt++;
                }
            }
        }
    } 
    return cnt;
}
}

The console return from this is the following:

1 012 2 013 3 014 4 023 5 024 6 034 7 123 8 124 9 134 10 234 0

That is the count of unique combinations of the integers provided. So I have looked up the formula for unique combinations of three digits from Maths is fun .

A brief synopsis of the '6' in the formula then. As each combination of 3 digits is appearing only once consider how many times you could order 3 digits (lets look at 1, 2 and 3):

123 132 213 231 312 321

6 times! but as this combination is appearing only once (123) we divide the total by 6 to find how many are returned. The details on the maths are further described on the link above, including the general solution regardless of the number of integers used, and the size of the loop.

The variables i, j, and k are taken from the set {0,1,...,N-1}. But they're always in order, so the number of possibilities is C(N,3)=N!/((N-3)!3!).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM