mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-03 09:14:38 +00:00
Add linear_search_reverse and linear_search_reverse_proc
This commit is contained in:
@@ -96,6 +96,14 @@ contains :: proc(array: $T/[]$E, value: E) -> bool where intrinsics.type_is_comp
|
||||
return found
|
||||
}
|
||||
|
||||
/*
|
||||
Searches the given element in the given slice in O(n) time.
|
||||
|
||||
Returns the first index at which the given element can be found in the slice,
|
||||
or -1 if it is not present.
|
||||
|
||||
If you need a custom compare procedure, see `linear_search_proc`
|
||||
*/
|
||||
@(require_results)
|
||||
linear_search :: proc(array: $A/[]$T, key: T) -> (index: int, found: bool)
|
||||
where intrinsics.type_is_comparable(T) #no_bounds_check {
|
||||
@@ -107,6 +115,12 @@ linear_search :: proc(array: $A/[]$T, key: T) -> (index: int, found: bool)
|
||||
return -1, false
|
||||
}
|
||||
|
||||
/*
|
||||
Searches the given element in the given slice in O(n) time, using the given predicate.
|
||||
|
||||
Returns the first index at which the given element can be found in the slice,
|
||||
or -1 if it is not present.
|
||||
*/
|
||||
@(require_results)
|
||||
linear_search_proc :: proc(array: $A/[]$T, f: proc(T) -> bool) -> (index: int, found: bool) #no_bounds_check {
|
||||
for x, i in array {
|
||||
@@ -117,6 +131,61 @@ linear_search_proc :: proc(array: $A/[]$T, f: proc(T) -> bool) -> (index: int, f
|
||||
return -1, false
|
||||
}
|
||||
|
||||
/*
|
||||
Reverse linear search searches the given element in the given slice in O(n) time,
|
||||
starting from the slice end.
|
||||
|
||||
Returns the last index at which the given element can be found in the slice,
|
||||
or -1 if it is not present
|
||||
|
||||
# Examples
|
||||
|
||||
```
|
||||
index: int
|
||||
found: bool
|
||||
|
||||
a := []i32{1, 1, 1, 2}
|
||||
|
||||
index, found = linear_search_reverse(a, 2)
|
||||
assert(index == 3 && found == true)
|
||||
|
||||
index, found = linear_search_reverse(a, 1)
|
||||
assert(index == 2 && found == true)
|
||||
|
||||
index, found = linear_search_reverse(a, 0)
|
||||
assert(index == -1 && found == false)
|
||||
```
|
||||
|
||||
If you need a custom compare procedure, see `linear_search_reverse_proc`
|
||||
*/
|
||||
@(require_results)
|
||||
linear_search_reverse :: proc(array: $A/[]$T, key: T) -> (index: int, found: bool)
|
||||
where intrinsics.type_is_comparable(T) #no_bounds_check {
|
||||
#reverse for x, i in array {
|
||||
if x == key {
|
||||
return i, true
|
||||
}
|
||||
}
|
||||
return -1, false
|
||||
}
|
||||
|
||||
/*
|
||||
Searches the given element in the given slice in O(n) time, starting from the end of
|
||||
the slice and using the given predicate.
|
||||
|
||||
Returns the last index at which the given element can be found in the slice,
|
||||
or -1 if it is not present
|
||||
*/
|
||||
@(require_results)
|
||||
linear_search_reverse_proc :: proc(array: $A/[]$T, f: proc(T) -> bool) -> (index: int, found: bool) #no_bounds_check {
|
||||
#reverse for x, i in array {
|
||||
if f(x) {
|
||||
return i, true
|
||||
}
|
||||
}
|
||||
return -1, false
|
||||
}
|
||||
|
||||
/*
|
||||
Binary search searches the given slice for the given element.
|
||||
If the slice is not sorted, the returned index is unspecified and meaningless.
|
||||
|
||||
@@ -306,3 +306,38 @@ test_compare_empty :: proc(t: ^testing.T) {
|
||||
testing.expectf(t, slice.equal(c[:], d[:]),
|
||||
"Expected two separate empty slices of two dynamic arrays to be equal")
|
||||
}
|
||||
|
||||
@test
|
||||
test_linear_search_reverse :: proc(t: ^testing.T) {
|
||||
index: int
|
||||
found: bool
|
||||
|
||||
s := []i32{0, 50, 50, 100}
|
||||
|
||||
index, found = slice.linear_search_reverse(s, 100)
|
||||
testing.expect(t, found)
|
||||
testing.expect_value(t, index, len(s) - 1)
|
||||
|
||||
index, found = slice.linear_search_reverse(s[len(s) - 1:], 100)
|
||||
testing.expect(t, found)
|
||||
testing.expect_value(t, index, 0)
|
||||
|
||||
index, found = slice.linear_search_reverse(s, 50)
|
||||
testing.expect(t, found)
|
||||
testing.expect_value(t, index, 2)
|
||||
|
||||
index, found = slice.linear_search_reverse(s, 0)
|
||||
testing.expect(t, found)
|
||||
testing.expect_value(t, index, 0)
|
||||
|
||||
index, found = slice.linear_search_reverse(s, -1)
|
||||
testing.expect(t, !found)
|
||||
|
||||
less_than_80 :: proc(x: i32) -> bool {
|
||||
return x < 80
|
||||
}
|
||||
|
||||
index, found = slice.linear_search_reverse_proc(s, less_than_80)
|
||||
testing.expect(t, found)
|
||||
testing.expect_value(t, index, 2)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user