mirror of
https://github.com/dlang/phobos.git
synced 2025-04-28 06:00:35 +03:00
[std.algorithm.searching] Add extrema
This commit is contained in:
parent
35c492c4ba
commit
6c7d0e2ef1
1 changed files with 67 additions and 2 deletions
|
@ -34,6 +34,7 @@ $(T2 commonPrefix,
|
||||||
`commonPrefix("parakeet", "parachute")` returns `"para"`.)
|
`commonPrefix("parakeet", "parachute")` returns `"para"`.)
|
||||||
$(T2 endsWith,
|
$(T2 endsWith,
|
||||||
`endsWith("rocks", "ks")` returns `true`.)
|
`endsWith("rocks", "ks")` returns `true`.)
|
||||||
|
$(T2 extrema, `extrema([2, 1, 3, 5, 4])` returns `[1, 5]`.)
|
||||||
$(T2 find,
|
$(T2 find,
|
||||||
`find("hello world", "or")` returns `"orld"` using linear search.
|
`find("hello world", "or")` returns `"orld"` using linear search.
|
||||||
(For binary search refer to $(REF SortedRange, std,range).))
|
(For binary search refer to $(REF SortedRange, std,range).))
|
||||||
|
@ -3684,7 +3685,7 @@ Note:
|
||||||
|
|
||||||
See_Also:
|
See_Also:
|
||||||
|
|
||||||
$(LREF maxElement), $(REF min, std,algorithm,comparison), $(LREF minCount),
|
$(LREF extrema), $(LREF maxElement), $(REF min, std,algorithm,comparison), $(LREF minCount),
|
||||||
$(LREF minIndex), $(LREF minPos)
|
$(LREF minIndex), $(LREF minPos)
|
||||||
*/
|
*/
|
||||||
auto minElement(alias map = (a => a), Range)(Range r)
|
auto minElement(alias map = (a => a), Range)(Range r)
|
||||||
|
@ -3865,7 +3866,7 @@ Note:
|
||||||
|
|
||||||
See_Also:
|
See_Also:
|
||||||
|
|
||||||
$(LREF minElement), $(REF max, std,algorithm,comparison), $(LREF maxCount),
|
$(LREF extrema), $(LREF minElement), $(REF max, std,algorithm,comparison), $(LREF maxCount),
|
||||||
$(LREF maxIndex), $(LREF maxPos)
|
$(LREF maxIndex), $(LREF maxPos)
|
||||||
*/
|
*/
|
||||||
auto maxElement(alias map = (a => a), Range)(Range r)
|
auto maxElement(alias map = (a => a), Range)(Range r)
|
||||||
|
@ -4035,6 +4036,70 @@ if (isInputRange!Range && !isInfinite!Range &&
|
||||||
assert(maxElement(arr) == S(145));
|
assert(maxElement(arr) == S(145));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns an array of the minimum and maximum element in `r`.
|
||||||
|
* Makes `< 3n/2` comparisons.
|
||||||
|
*/
|
||||||
|
// TODO alias map = a => a
|
||||||
|
ElementType!Range[2] extrema(Range)(Range r)
|
||||||
|
if (isRandomAccessRange!Range && hasLength!Range)
|
||||||
|
in (!r.empty)
|
||||||
|
{
|
||||||
|
if (r.length == 1)
|
||||||
|
return [r[0], r[0]];
|
||||||
|
|
||||||
|
typeof(return) result;
|
||||||
|
size_t i;
|
||||||
|
if (r.length & 1) // odd
|
||||||
|
{
|
||||||
|
result = [r[0], r[0]];
|
||||||
|
i = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = (r[0] < r[1]) ? [r[0], r[1]] : [r[1], r[0]];
|
||||||
|
i = 2;
|
||||||
|
}
|
||||||
|
// iterate pairs
|
||||||
|
const imax = r.length;
|
||||||
|
for (; i != imax; i += 2)
|
||||||
|
{
|
||||||
|
// save work
|
||||||
|
if (r[i] < r[i+1])
|
||||||
|
{
|
||||||
|
if (r[i] < result[0])
|
||||||
|
result[0] = r[i];
|
||||||
|
if (r[i+1] > result[1])
|
||||||
|
result[1] = r[i+1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (r[i+1] < result[0])
|
||||||
|
result[0] = r[i+1];
|
||||||
|
if (r[i] > result[1])
|
||||||
|
result[1] = r[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
assert(extrema([5,2,9,4,1]) == [1, 9]);
|
||||||
|
assert(extrema([8,3,7,4,9]) == [3, 9]);
|
||||||
|
assert(extrema([1,5,3,2]) == [1, 5]);
|
||||||
|
assert(extrema([2,3,3,2]) == [2, 3]);
|
||||||
|
|
||||||
|
version (StdRandomTests)
|
||||||
|
foreach (i; 0..1000)
|
||||||
|
{
|
||||||
|
import std.random, std.range;
|
||||||
|
auto arr = generate!(() => uniform(0, 100)).takeExactly(uniform(1, 10)).array;
|
||||||
|
auto result = arr.extrema;
|
||||||
|
assert(result[0] == arr.minElement);
|
||||||
|
assert(result[1] == arr.maxElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// minPos
|
// minPos
|
||||||
/**
|
/**
|
||||||
Computes a subrange of `range` starting at the first occurrence of `range`'s
|
Computes a subrange of `range` starting at the first occurrence of `range`'s
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue