ENH: add list operation findMinMax to return label pair.

- when both min and max are required, this is more efficient than
  traversing the list twice.
This commit is contained in:
Mark Olesen
2018-08-06 08:46:32 +02:00
parent bf56b06be2
commit 2290b0642e
2 changed files with 59 additions and 9 deletions

View File

@ -43,6 +43,7 @@ SourceFiles
#define ListOps_H
#include "FlatOutput.H"
#include "labelPair.H"
#include "labelList.H"
#include "HashSet.H"
#include "Map.H"
@ -360,7 +361,21 @@ labelList findIndices
label start=0
);
//- Linear search for the index of the max element.
//- Linear search for the index of the min element,
//- similar to std::min_element but for lists and returns the index.
//
// \tparam ListType The input list type
//
// \param input The list to search
// \param start The start index in the list (default: 0)
//
// \return The min index or -1 on error.
template<class ListType>
label findMin(const ListType& input, label start=0);
//- Linear search for the index of the max element,
//- similar to std::max_element but for lists and returns the index.
//
// \tparam ListType The input list type
//
@ -372,16 +387,18 @@ template<class ListType>
label findMax(const ListType& input, label start=0);
//- Linear search for the index of the min element.
//- Linear search for the index of the min/max element,
//- similar to std::minmax_element but for lists and returns the index.
//
// \tparam ListType The input list type
//
// \param input The list to search
// \param start The start index in the list (default: 0)
//
// \return The min index or -1 on error.
// \return The min/max indices as a Pair (min is first max is second)
// or (-1,-1) on error.
template<class ListType>
label findMin(const ListType& input, label start=0);
labelPair findMinMax(const ListType& input, label start=0);
//- Binary search to find the index of the last element in a sorted list

View File

@ -671,6 +671,32 @@ Foam::labelList Foam::findIndices
}
template<class ListType>
Foam::label Foam::findMin
(
const ListType& input,
label start
)
{
const label len = input.size();
if (start < 0 || start >= len)
{
return -1;
}
for (label i = start+1; i < len; ++i)
{
if (input[i] < input[start])
{
start = i;
}
}
return start;
}
template<class ListType>
Foam::label Foam::findMax
(
@ -698,7 +724,7 @@ Foam::label Foam::findMax
template<class ListType>
Foam::label Foam::findMin
Foam::labelPair Foam::findMinMax
(
const ListType& input,
label start
@ -708,18 +734,25 @@ Foam::label Foam::findMin
if (start < 0 || start >= len)
{
return -1;
return labelPair(-1,-1);
}
label minIdx = start;
label maxIdx = start;
for (label i = start+1; i < len; ++i)
{
if (input[i] < input[start])
if (input[i] < input[minIdx])
{
start = i;
minIdx = i;
}
if (input[maxIdx] < input[i])
{
maxIdx = i;
}
}
return start;
return labelPair(minIdx, maxIdx);
}