mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 14:40:30 +03:00
commit
02c0083e1c
2 changed files with 80 additions and 19 deletions
|
@ -34,7 +34,9 @@ $(TR $(TDNW Searching)
|
|||
$(SUBREF searching, findSplitAfter)
|
||||
$(SUBREF searching, findSplitBefore)
|
||||
$(SUBREF searching, minCount)
|
||||
$(SUBREF searching, maxCount)
|
||||
$(SUBREF searching, minPos)
|
||||
$(SUBREF searching, maxPos)
|
||||
$(SUBREF searching, skipOver)
|
||||
$(SUBREF searching, startsWith)
|
||||
$(SUBREF searching, until)
|
||||
|
|
|
@ -57,10 +57,16 @@ $(T2 findSplitBefore,
|
|||
and $(D "defg").)
|
||||
$(T2 minCount,
|
||||
$(D minCount([2, 1, 1, 4, 1])) returns $(D tuple(1, 3)).)
|
||||
$(T2 maxCount,
|
||||
$(D maxCount([2, 4, 1, 4, 1])) returns $(D tuple(4, 2)).)
|
||||
$(T2 minPos,
|
||||
$(D minPos([2, 3, 1, 3, 4, 1])) returns the subrange $(D [1, 3, 4, 1]),
|
||||
i.e., positions the range at the first occurrence of its minimal
|
||||
element.)
|
||||
$(T2 maxPos,
|
||||
$(D maxPos([2, 3, 1, 3, 4, 1])) returns the subrange $(D [4, 1]),
|
||||
i.e., positions the range at the first occurrence of its maximal
|
||||
element.)
|
||||
$(T2 mismatch,
|
||||
$(D mismatch("parakeet", "parachute")) returns the two ranges
|
||||
$(D "keet") and $(D "chute").)
|
||||
|
@ -2718,15 +2724,32 @@ if (isForwardRange!R1 && isForwardRange!R2)
|
|||
assert(equal(r2[1], a[4 .. $]));
|
||||
}
|
||||
|
||||
// minCount
|
||||
/**
|
||||
|
||||
Computes the minimum (respectively maximum) of `range` along with its number of
|
||||
occurrences. Formally, the minimum is a value `x` in `range` such that $(D
|
||||
pred(a, x)) is `false` for all values `a` in `range`. Conversely, the maximum is
|
||||
a value `x` in `range` such that $(D pred(x, a)) is `false` for all values `a`
|
||||
in `range` (note the swapped arguments to `pred`).
|
||||
|
||||
These functions may be used for computing arbitrary extrema by choosing `pred`
|
||||
appropriately. For corrrect functioning, `pred` must be a strict partial order,
|
||||
i.e. transitive (if $(D pred(a, b) && pred(b, c)) then $(D pred(a, c))) and
|
||||
irreflexive ($(D pred(a, a)) is `false`). The $(LUCKY trichotomy property of
|
||||
inequality) is not required: these algoritms consider elements `a` and `b` equal
|
||||
(for the purpose of counting) if `pred` puts them in the same equivalence class,
|
||||
i.e. $(D !pred(a, b) && !pred(b, a)).
|
||||
|
||||
Params:
|
||||
pred = The ordering predicate to use to determine the minimal element.
|
||||
pred = The ordering predicate to use to determine the extremum (minimum
|
||||
or maximum).
|
||||
range = The input range to count.
|
||||
|
||||
Returns: The minimum element of a range together with the number of
|
||||
occurrences. The function can actually be used for counting the
|
||||
maximum or any other ordering predicate (that's why $(D maxCount) is
|
||||
not provided).
|
||||
Returns: The minimum, respectively maximum element of a range together with the
|
||||
number it occurs in the range.
|
||||
|
||||
Throws: `Exception` if `range.empty`.
|
||||
*/
|
||||
Tuple!(ElementType!Range, size_t)
|
||||
minCount(alias pred = "a < b", Range)(Range range)
|
||||
|
@ -2752,7 +2775,12 @@ minCount(alias pred = "a < b", Range)(Range range)
|
|||
Range least = range.save;
|
||||
for (range.popFront(); !range.empty; range.popFront())
|
||||
{
|
||||
if (binaryFun!pred(least.front, range.front)) continue;
|
||||
if (binaryFun!pred(least.front, range.front))
|
||||
{
|
||||
assert(!binaryFun!pred(range.front, least.front),
|
||||
"min/maxPos: predicate must be a strict partial order.");
|
||||
continue;
|
||||
}
|
||||
if (binaryFun!pred(range.front, least.front))
|
||||
{
|
||||
// change the min
|
||||
|
@ -2809,6 +2837,15 @@ minCount(alias pred = "a < b", Range)(Range range)
|
|||
"to keep track of the smallest %s element.", Range.stringof, T.stringof));
|
||||
}
|
||||
|
||||
/// Ditto
|
||||
Tuple!(ElementType!Range, size_t)
|
||||
maxCount(alias pred = "a < b", Range)(Range range)
|
||||
if (isInputRange!Range && !isInfinite!Range &&
|
||||
is(typeof(binaryFun!pred(range.front, range.front))))
|
||||
{
|
||||
return range.minCount!((a, b) => binaryFun!pred(b, a));
|
||||
}
|
||||
|
||||
///
|
||||
unittest
|
||||
{
|
||||
|
@ -2819,9 +2856,9 @@ unittest
|
|||
|
||||
int[] a = [ 2, 3, 4, 1, 2, 4, 1, 1, 2 ];
|
||||
// Minimum is 1 and occurs 3 times
|
||||
assert(minCount(a) == tuple(1, 3));
|
||||
assert(a.minCount == tuple(1, 3));
|
||||
// Maximum is 4 and occurs 2 times
|
||||
assert(minCount!("a > b")(a) == tuple(4, 2));
|
||||
assert(a.maxCount == tuple(4, 2));
|
||||
}
|
||||
|
||||
unittest
|
||||
|
@ -2913,15 +2950,29 @@ unittest
|
|||
|
||||
// minPos
|
||||
/**
|
||||
Computes a subrange of `range` starting at the first occurrence of `range`'s
|
||||
minimum (respectively maximum) and with the same ending as `range`, or the
|
||||
empty range if `range` itself is empty.
|
||||
|
||||
Formally, the minimum is a value `x` in `range` such that $(D pred(a, x)) is
|
||||
`false` for all values `a` in `range`. Conversely, the maximum is a value `x` in
|
||||
`range` such that $(D pred(x, a)) is `false` for all values `a` in `range` (note
|
||||
the swapped arguments to `pred`).
|
||||
|
||||
These functions may be used for computing arbitrary extrema by choosing `pred`
|
||||
appropriately. For corrrect functioning, `pred` must be a strict partial order,
|
||||
i.e. transitive (if $(D pred(a, b) && pred(b, c)) then $(D pred(a, c))) and
|
||||
irreflexive ($(D pred(a, a)) is `false`).
|
||||
|
||||
Params:
|
||||
pred = The ordering predicate to use to determine the minimal element.
|
||||
pred = The ordering predicate to use to determine the extremum (minimum or
|
||||
maximum) element.
|
||||
range = The input range to search.
|
||||
|
||||
Returns: The position of the minimum element of forward range $(D range), i.e.
|
||||
a subrange of $(D range) starting at the position of its smallest element and
|
||||
with the same ending as $(D range). The function can actually be used for
|
||||
finding the maximum or any other ordering predicate (that's why $(D maxPos) is
|
||||
not provided).
|
||||
Returns: The position of the minimum (respectively maximum) element of forward
|
||||
range `range`, i.e. a subrange of `range` starting at the position of its
|
||||
smallest (respectively largest) element and with the same ending as `range`.
|
||||
|
||||
*/
|
||||
Range minPos(alias pred = "a < b", Range)(Range range)
|
||||
if (isForwardRange!Range && !isInfinite!Range &&
|
||||
|
@ -2958,14 +3009,22 @@ Range minPos(alias pred = "a < b", Range)(Range range)
|
|||
}
|
||||
}
|
||||
|
||||
/// Ditto
|
||||
Range maxPos(alias pred = "a < b", Range)(Range range)
|
||||
if (isForwardRange!Range && !isInfinite!Range &&
|
||||
is(typeof(binaryFun!pred(range.front, range.front))))
|
||||
{
|
||||
return range.minPos!((a, b) => binaryFun!pred(b, a));
|
||||
}
|
||||
|
||||
///
|
||||
@safe unittest
|
||||
{
|
||||
int[] a = [ 2, 3, 4, 1, 2, 4, 1, 1, 2 ];
|
||||
// Minimum is 1 and first occurs in position 3
|
||||
assert(minPos(a) == [ 1, 2, 4, 1, 1, 2 ]);
|
||||
assert(a.minPos == [ 1, 2, 4, 1, 1, 2 ]);
|
||||
// Maximum is 4 and first occurs in position 2
|
||||
assert(minPos!("a > b")(a) == [ 4, 1, 2, 4, 1, 1, 2 ]);
|
||||
assert(a.maxPos == [ 4, 1, 2, 4, 1, 1, 2 ]);
|
||||
}
|
||||
|
||||
@safe unittest
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue