As @emory pointed out, it is provably impossible to determine the big-O time complexity of an arbitrary piece of code automatically (the proof is a reduction from the halting problem). However, there are tools that can attempt to measure the complexity of a piece of code empirically by running it on several different inputs. One such tool is described in the paper “Measuring Empirical Computational Complexity” by Goldsmith, Aiken, and Wilkerson. It works by attempting to do a regression on the program's runtime versus its input size. The tool, called trend-prof, has been discontinued, but is archived here for reference.
Answer from templatetypedef on Stack OverflowVideos
As @emory pointed out, it is provably impossible to determine the big-O time complexity of an arbitrary piece of code automatically (the proof is a reduction from the halting problem). However, there are tools that can attempt to measure the complexity of a piece of code empirically by running it on several different inputs. One such tool is described in the paper “Measuring Empirical Computational Complexity” by Goldsmith, Aiken, and Wilkerson. It works by attempting to do a regression on the program's runtime versus its input size. The tool, called trend-prof, has been discontinued, but is archived here for reference.
I might be solving someone's homework, but the question was begging for a sane solution...
Counting distinct digits in a number requires no strings, sets or regular expressions, just some simple arithmetics.
The following method runs in O(n) time (n = number of digits in the input) and constant space:
Copyint distinctDigits(int num) {
if (num == 0) {
return 1;
}
boolean[] digits = new boolean[10];
while (num > 0) {
digits[num % 10] = true;
num /= 10;
}
int count = 0;
for (boolean digit : digits) {
if (digit) {
count++;
}
}
return count;
}
Making this work for negative numbers is left as an exericse to the reader ;)
The time complexity of your code can be understood as follows:
The outer loop (i.e., for(ArrayList doc : documents)) will run as many times as there are documents in your input list. So if there are n documents, this loop runs n times.
The inner loop (i.e., for(int i=0; i<doc.size-1; i++)) will run as many times as there are words in each document. So if there are m words in each document, the inner loop runs m times.
So overall, the time complexity of your code can be considered as O(n*m).
However, this is not the final complexity. The HashMap operation counter.compute() also has a time complexity which is usually O(1) in the average case but can be O(n) in the worst case where n is the number of elements in the map. But since HashMap operations are generally considered to have a time complexity of O(1) in average case scenarios, we usually consider the time complexity of your code to be O(n*m).
In terms of improving your code:you can use a pair of strings as the key to your HashMap instead of concatenating the strings(You can create a simple Pair class for this purpose) or u can use the Map.merge() method instead of Map.compute().These will make it easier to manipulate and understand. But these changes are not going to change the time complexity of your code.
The time complexity of your code can be calculated as follows:
- Your outer for loop iterates over n documents in the given ArrayList (
O(n)) - The inner for loop iterates m times over the current document (
O(m))
Therefore, I would say the time complexity of the provided code snippet is O(n * m) in the worst case, where "n" represents the number of documents and "m" represents the average size of the documents.
Good luck!