Mercurial > repos > prog > lcmsmatching
comparison search.R @ 6:f86fec07f392 draft default tip
planemo upload commit c397cd8a93953798d733fd62653f7098caac30ce
author | prog |
---|---|
date | Fri, 22 Feb 2019 16:04:22 -0500 |
parents | fb9c0409d85c |
children |
comparison
equal
deleted
inserted
replaced
5:fb9c0409d85c | 6:f86fec07f392 |
---|---|
1 if ( ! exists('binary.search')) { # Do not load again if already loaded | |
2 | |
3 # Run a binary search on a sorted array. | |
4 # val The value to search. | |
5 # tab The array of values, sorted in ascending order. | |
6 # lower If set to NA, then search for the first value found by the binary search. If set to TRUE, find the value with the lowest index in the array. If set to FALSE, find the value with the highest index in the array. | |
7 # first The index of the array from which to start (1 by default). | |
8 # last The index of the array where to stop searching (end of the array by default). | |
9 # Returns the index of the found value, or NA. | |
10 binary.search <- function(val, tab, lower = NA, first = 1L, last = length(tab)) | |
11 { | |
12 # Check array & value | |
13 if (is.null(tab)) | |
14 stop('Argument "tab" is NULL.') | |
15 if (is.null(val)) | |
16 stop('Argument "val" is NULL.') | |
17 | |
18 # Wrong arguments | |
19 if (is.na(val) || last < first || length(tab) == 0) | |
20 return(NA_integer_) | |
21 | |
22 # Find value | |
23 l <- first | |
24 h <- last | |
25 while (h >= l) { | |
26 | |
27 # Take middle point | |
28 m <- (h + l) %/% 2 | |
29 # Found value | |
30 if (tab[m] == val) { | |
31 if (is.na(lower)) | |
32 return(m) | |
33 if (lower && m > first) { | |
34 for (i in (m-1):first) | |
35 if (tab[i] != val) | |
36 return(i+1) | |
37 } | |
38 else if ( ! lower && m < last) | |
39 for (i in (m+1):last) | |
40 if (tab[i] != val) | |
41 return(i-1) | |
42 return(m) | |
43 } | |
44 | |
45 # Decrease higher bound | |
46 else if (tab[m] > val) h <- m - 1 | |
47 | |
48 # Increase lower bound | |
49 else l <- m + 1 | |
50 } | |
51 | |
52 # Value not found | |
53 if ( ! is.na(lower)) { | |
54 # Look for lower or higher bound | |
55 if (lower) | |
56 return(if (h < first) NA_integer_ else h) | |
57 else | |
58 return(if (l > last) NA_integer_ else l) | |
59 } | |
60 | |
61 return(NA_integer_) | |
62 } | |
63 | |
64 } # end of load safe guard |