casa
$Rev:20696$
|
00001 //# BinarySearch.h: Binary search through linear, sorted, data structures 00002 //# Copyright (C) 1995,1996,1999 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have received a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00018 //# 00019 //# Correspondence concerning AIPS++ should be addressed as follows: 00020 //# Internet email: aips2-request@nrao.edu. 00021 //# Postal address: AIPS++ Project Office 00022 //# National Radio Astronomy Observatory 00023 //# 520 Edgemont Road 00024 //# Charlottesville, VA 22903-2475 USA 00025 //# 00026 //# 00027 //# $Id: BinarySearch.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $ 00028 00029 00030 #ifndef CASA_BINARYSEARCH_H 00031 #define CASA_BINARYSEARCH_H 00032 00033 //# Includes 00034 #include <casa/aips.h> 00035 00036 namespace casa { //# NAMESPACE CASA - BEGIN 00037 00038 // <summary> 00039 // Binary search a sorted, linear, data structure. 00040 // </summary> 00041 00042 // <reviewed reviewer="Ger van Diepen" date="1995/03/31" tests="tBinarySearch" demos=""> 00043 // </reviewed> 00044 00045 // <synopsis> 00046 // These binary search functions work on sorted, linear data structures 00047 // which have operator() or operator[] defined on them (<i>e.g.</i> 00048 // C-array, Vector, IPosition, Block, ScalarColumn, <i>etc.</i>) 00049 // Two versions of the functions are provided, one which uses 00050 // parentheses () for indexing, one which uses square brackets [] (obviously 00051 // the latter one can also be used for ordinary C-style pointers and arrays). 00052 // It is assumed that the container uses zero-based indexing. 00053 // 00054 // The container must be sorted (sorting is available through the 00055 // <linkto class="Sort">Sort</linkto> and 00056 // <linkto class="GenSort">GenSort</linkto> 00057 // classes, and from various 00058 // <linkto class="Table">Table</linkto> sort functions). The returned index 00059 // is in the range [0..n] inclusive. That is, from the first element of the 00060 // container to one past the last element of the container (zero-based indices). 00061 // If the container is sorted in ascending order, the returned index is the 00062 // first one whose element is greater than or equal to the searched for value. 00063 // If it is sorted in descending order, the returned index is the first which 00064 // is less than or equal to the searched for value. That is, the returned 00065 // index gives the position at which the value would be inserted (possibly 00066 // either at the end, or requiring the existing values to be "pushed" to the 00067 // right) maintaining the sort order. Obviously index n can only be 00068 // returned if the value searched for is past the end of the array, thus 00069 // has to be inserted at the end. 00070 // 00071 // The functions determine for themselves whether the container is sorted in 00072 // ascending or descending order by comparing the first and last element. 00073 // <note role=tip> 00074 // While normally you want to search a container with indices in the range 00075 // <src>[0 ... n-1]</src>, any desired lower bound may be used instead. 00076 // </note> 00077 // <note role=warning> 00078 // The functions do not check if the container is valid, <i>i.e.</i> if 00079 // the container is sorted and if the container does not contain duplicate 00080 // values. 00081 // </note> 00082 // 00083 // These functions loosely follow some written by Ger van Diepen in a more 00084 // specialized context. 00085 // </synopsis> 00086 // 00087 // <example> 00088 // <srcblock> 00089 // Vector<Int> vi; 00090 // ... // Sets vi somehow 00091 // genSort(vi); 00092 // Int val; 00093 // Bool found; 00094 // while (cin >> val && val != -999) { 00095 // Int where = binarySearch(found, vi, val, vi.nelements()); 00096 // if (found) { 00097 // cout << "Found " << val << " at position " << where << endl; 00098 // } else { 00099 // cout << val << " is not in the vector, but it belongs at " << 00100 // where << endl; 00101 // } 00102 // } 00103 // </srcblock> 00104 // </example> 00105 // 00106 // <motivation> 00107 // I found that I (BEG) was writing binary search functions several times, 00108 // for example when checking whether the cached off and gain scans in time 00109 // sorted data needed to be refilled. It generally seems like a useful little 00110 // utility function. 00111 // </motivation> 00112 // 00113 // <templating arg=Container> 00114 // <li> operator(Int) or operator[Int] needs to be defined. 00115 // <li> The index must be zero based. 00116 // <li> The result of that indexing must be an expression that can be 00117 // compared with an object of class ElType. Normally in fact it would 00118 // be a temporary of class ElType. 00119 // </templating> 00120 // <templating arg=ElType> 00121 // <li> The less than operator (<) and greater than (>) operators need to 00122 // be defined, and have their usual ordering relations. 00123 // </templating> 00124 // 00125 // <todo asof="yyyy/mm/dd"> 00126 // <li> I suspect that an implementation is possible that only calls 00127 // operator() or [] once during each evaluation of the while loop. 00128 // <li> MACROize implementation so that code isn't repeated twice. Or, 00129 // possibly implement one using the other (e.g. by introducing an adapter 00130 // class that turns (i) into [i]. 00131 // </todo> 00132 00133 00134 // <group name=binarysearch> 00135 00136 // Search <i>container</i> for <i>value</i>. There are assumed to be at least 00137 // <i>n</i> elements in the container. The container will be searched for 00138 // indices in the range <src>[lower ... lower + n - 1]</src> Return the index 00139 // of the first element which is greater than or equal to (ascending order) or 00140 // less than or equal to (descending order) the value. 00141 // <group> 00142 // This version of the function is for containers that use () for indexing. 00143 template<class Container, class ElType> 00144 Int binarySearch(Bool &found, const Container &container, 00145 const ElType &value, uInt n, Int lower=0); 00146 // This version of the function is for containers that use [] for indexing. 00147 template<class Container, class ElType> 00148 Int binarySearchBrackets(Bool &found, const Container &container, 00149 const ElType &value, uInt n, Int lower=0); 00150 // </group> 00151 // </group> 00152 00153 00154 } //# NAMESPACE CASA - END 00155 00156 #ifndef CASACORE_NO_AUTO_TEMPLATES 00157 #include <casa/Utilities/BinarySearch.tcc> 00158 #endif //# CASACORE_NO_AUTO_TEMPLATES 00159 #endif