问题
Following on from my previous question, can we prove that the standard allows us to pass an empty range to a standard algorithm?
Paragraph 24.1/7 defines an "empty range" as the range [i,i)
(where i
is valid), and i
would appear to be "reachable" from itself, but I'm not sure that this qualifies as a proof.
In particular, we run into trouble when looking at the sorting functions. For example, std::sort
:
Complexity:
O(N log(N))
(whereN
==last
-first
) comparisons
Since log(0)
is generally considered to be undefined, and I don't know what 0*undefined
is, could there be a problem here?
(Yes, ok, I'm being a bit pedantic. Of course no self-respecting stdlib implementation would cause a practical problem with an empty range passed to std::sort
. But I'm wondering whether there's a potential hole in the standard wording here.)
回答1:
I don't seem much room for question. In §24.1/6 we're told:
An iterator j is called reachable from an iterator i if and only if there is a finite sequence of applications of the expression ++i that makes i == j.
and in $24.1/7:
Range [i, j) is valid if and only if j is reachable from i.
Since 0
is finite, [i, i)
is a valid range. §24.1/7 goes on to say:
The result of the application of functions in the library to invalid ranges is undefined.
That doesn't go quite so far as to say that a valid range guarantees defined results (reasonable, since there are other requirements, such as on the comparison function) but certainly seems to imply that a range being empty, in itself, should not lead to UB or anything like that. In particular, however, the standard makes an empty range just another valid range; there's no real differentiation between empty and non-empty valid ranges, so what applies to a non-empty valid range applies equally well to an empty valid range.
回答2:
Big-O notation is defined in terms of the limit of the function. An algorithm with actual running time g(N)
is O(f(N))
if and only if lim N→∞ g(N)/f(N)
is a non-negative real numberg(N)/f(N)
is less than some positive real number C
for all values N
greater than some constant k
(the exact values of C
and k
are immaterial; you just have to be able to find any C
and k
that makes this true). (thanks for the correction, Jesse!)
You'll note that the actual number of elements is not relevant in big-O analysis. Big-O analysis says nothing about the behavior of the algorithm for small numbers of elements; therefore, it does not matter if f(N)
is defined at N=0
. More importantly, the actual runtime behavior is controlled by a different function g(N)
, which may well be defined at N=0
even if f(0)
is undefined.
回答3:
Apart from the relevant answer given by @bdonlan, note also that f(n) = n * log(n)
does have a well-defined limit as n
goes to zero, namely 0
. This is because the logarithm diverges more slowly than any polynomial, in particular, slower than n
. So all is well :-)
来源:https://stackoverflow.com/questions/7505267/is-it-defined-to-provide-an-empty-range-to-c-standard-algorithms