Question: I am writing a simple program to take a file, encrypt it with AES, and store the output in a separate file using Java. Java is a new language for me, but it's similar to C# in some ways and I've been using C# for a while so the learning as been going relatively smoothly.

My question is that I would like to run the AES cipher in a separate thread, which seems easy enough, but I would like to be able to report an approximate progress to the user in a Swing progress bar. I don't know how to get a status of the encryption to be able to report that back to the user. 

I did have an idea, and I wanted to get input on that unless there is a significantly easier way to do it. My idea was to, before the encryption starts, get a size of the input file in bytes, then, on a timer, find the number of bytes that are currently in the output file to determine the percentage complete. However, I do wonder if I'll be able to open a new file handle on the output file when I will have an open handle in another thread in Java. Is my solution possible or is there an easier way to do it?

Answer: 
What you're looking for in big O time complexity is the approximate number of times an instruction is executed. So, in the first function, you have the executable statement:

```
intMatrix[i][j] = 0;

```

Since the executable statement takes the same amount of time every time, it is O(1). So, for the first function, you can cut it down to look like this and work back from the executable statement:

```
i: execute n times{//Time complexity=n*(n+1)/2
    j: execute i times{
        intMatrix[i][j] = 0; //Time complexity=1
    }
}

```

Working back, the both the i loop executes n times and the j loop executes i times. For example, if n = 5, the number of instructions executed would be 5+4+3+2+1=15. This is an arithmetic series, and can be represented by n(n+1)/2. The time complexity of the function is therefore n(n+1)/2=n^2/2+n/2=**O(n^2)**.

For the second function, you're looking at something similar. Your executable statement is:

```
dividend[j] = dividend[j] / divisor[i];

```

Now, with this statement it's a little more complicated, as you can see from [wikipedia](http://en.wikipedia.org/wiki/Computational_complexity_of_mathematical_operations), complexity of schoolbook long division is O(n^2). However, the dividend and divisor DO NOT use your variable n, so they're not dependent on it. Let's call the dividend and divisor, aka the actual contents of the matrix "m". So the time complexity of the executable statement is O(m^2). Moving on to simplify the second function:

```
i: execute n times{ //Time complexity=n*(n*(1*m^2))=O(n^2*m^2)
    j: execute n times{ //Time complexity=n*(1*m^2)
        if statement: execute ONCE{ //Time complexity=1*m^2
            dividend[j] = dividend[j] / divisor[i]; //Time complexity=m^2
        }
    }
}

```

Working backwards, you can see that the inner statement will take O(m^2), and since the if statement takes the same amount of time every time, its time complexity is O(1). Your final answer is then O(n^2m^2). Since division takes so little time on modern processors, it is usually estimated at O(1) (see [this](http://www.quora.com/Computational-Complexity-Theory/Whats-the-computational-cost-of-the-division-operation) for a better explanation for why this is), what your professor is probably looking for O(n^2) for the second function.
Big O Notation or time complexity, describes the relationship between a change in data size (n), and the magnitude of time / space required for a given algorithm to process it.

In your case you have two loops. For each number of n (the outer loop), you process n items (in the inner loop) items. Thus in you have O(n2) or "quadratic" time complexity.

So for small numbers of n the difference is negligible, but for larger numbers of n, it quickly grinds to a halt.

Eliminating 0 from the divisor as in algorithm 2 does not significantly change the time complexity, because checking to see if a number = 0 is O(1) and several orders of magnitude less then O(n2). Eliminating the inner loop in that specific case is still O(n), and still dwarfed by the time it takes to do the O(n2). Your second algorithm, thus technically becomes (best case) O(n) (if there are only zeros in the divisor series).