| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- // Copyright 2014 The sortutil Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- // Package sortutil provides utilities supplementing the standard 'sort' package.
- //
- // Changelog
- //
- // 2019-10-24: v1.1.0: Added topological sort.
- //
- // 2015-06-17: Added utils for math/big.{Int,Rat}.
- package sortutil // import "modernc.org/sortutil"
- import (
- "math/big"
- )
- import "sort"
- // BigIntSlice attaches the methods of sort.Interface to []*big.Int, sorting in increasing order.
- type BigIntSlice []*big.Int
- func (s BigIntSlice) Len() int { return len(s) }
- func (s BigIntSlice) Less(i, j int) bool { return s[i].Cmp(s[j]) < 0 }
- func (s BigIntSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
- // Sort is a convenience method.
- func (s BigIntSlice) Sort() {
- sort.Sort(s)
- }
- // SearchBigInts searches for x in a sorted slice of *big.Int and returns the index
- // as specified by sort.Search. The slice must be sorted in ascending order.
- func SearchBigInts(a []*big.Int, x *big.Int) int {
- return sort.Search(len(a), func(i int) bool { return a[i].Cmp(x) >= 0 })
- }
- // BigRatSlice attaches the methods of sort.Interface to []*big.Rat, sorting in increasing order.
- type BigRatSlice []*big.Rat
- func (s BigRatSlice) Len() int { return len(s) }
- func (s BigRatSlice) Less(i, j int) bool { return s[i].Cmp(s[j]) < 0 }
- func (s BigRatSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
- // Sort is a convenience method.
- func (s BigRatSlice) Sort() {
- sort.Sort(s)
- }
- // SearchBigRats searches for x in a sorted slice of *big.Int and returns the index
- // as specified by sort.Search. The slice must be sorted in ascending order.
- func SearchBigRats(a []*big.Rat, x *big.Rat) int {
- return sort.Search(len(a), func(i int) bool { return a[i].Cmp(x) >= 0 })
- }
- // ByteSlice attaches the methods of sort.Interface to []byte, sorting in increasing order.
- type ByteSlice []byte
- func (s ByteSlice) Len() int { return len(s) }
- func (s ByteSlice) Less(i, j int) bool { return s[i] < s[j] }
- func (s ByteSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
- // Sort is a convenience method.
- func (s ByteSlice) Sort() {
- sort.Sort(s)
- }
- // SearchBytes searches for x in a sorted slice of bytes and returns the index
- // as specified by sort.Search. The slice must be sorted in ascending order.
- func SearchBytes(a []byte, x byte) int {
- return sort.Search(len(a), func(i int) bool { return a[i] >= x })
- }
- // Float32Slice attaches the methods of sort.Interface to []float32, sorting in increasing order.
- type Float32Slice []float32
- func (s Float32Slice) Len() int { return len(s) }
- func (s Float32Slice) Less(i, j int) bool { return s[i] < s[j] }
- func (s Float32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
- // Sort is a convenience method.
- func (s Float32Slice) Sort() {
- sort.Sort(s)
- }
- // SearchFloat32s searches for x in a sorted slice of float32 and returns the index
- // as specified by sort.Search. The slice must be sorted in ascending order.
- func SearchFloat32s(a []float32, x float32) int {
- return sort.Search(len(a), func(i int) bool { return a[i] >= x })
- }
- // Int8Slice attaches the methods of sort.Interface to []int8, sorting in increasing order.
- type Int8Slice []int8
- func (s Int8Slice) Len() int { return len(s) }
- func (s Int8Slice) Less(i, j int) bool { return s[i] < s[j] }
- func (s Int8Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
- // Sort is a convenience method.
- func (s Int8Slice) Sort() {
- sort.Sort(s)
- }
- // SearchInt8s searches for x in a sorted slice of int8 and returns the index
- // as specified by sort.Search. The slice must be sorted in ascending order.
- func SearchInt8s(a []int8, x int8) int {
- return sort.Search(len(a), func(i int) bool { return a[i] >= x })
- }
- // Int16Slice attaches the methods of sort.Interface to []int16, sorting in increasing order.
- type Int16Slice []int16
- func (s Int16Slice) Len() int { return len(s) }
- func (s Int16Slice) Less(i, j int) bool { return s[i] < s[j] }
- func (s Int16Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
- // Sort is a convenience method.
- func (s Int16Slice) Sort() {
- sort.Sort(s)
- }
- // SearchInt16s searches for x in a sorted slice of int16 and returns the index
- // as specified by sort.Search. The slice must be sorted in ascending order.
- func SearchInt16s(a []int16, x int16) int {
- return sort.Search(len(a), func(i int) bool { return a[i] >= x })
- }
- // Int32Slice attaches the methods of sort.Interface to []int32, sorting in increasing order.
- type Int32Slice []int32
- func (s Int32Slice) Len() int { return len(s) }
- func (s Int32Slice) Less(i, j int) bool { return s[i] < s[j] }
- func (s Int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
- // Sort is a convenience method.
- func (s Int32Slice) Sort() {
- sort.Sort(s)
- }
- // SearchInt32s searches for x in a sorted slice of int32 and returns the index
- // as specified by sort.Search. The slice must be sorted in ascending order.
- func SearchInt32s(a []int32, x int32) int {
- return sort.Search(len(a), func(i int) bool { return a[i] >= x })
- }
- // Int64Slice attaches the methods of sort.Interface to []int64, sorting in increasing order.
- type Int64Slice []int64
- func (s Int64Slice) Len() int { return len(s) }
- func (s Int64Slice) Less(i, j int) bool { return s[i] < s[j] }
- func (s Int64Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
- // Sort is a convenience method.
- func (s Int64Slice) Sort() {
- sort.Sort(s)
- }
- // SearchInt64s searches for x in a sorted slice of int64 and returns the index
- // as specified by sort.Search. The slice must be sorted in ascending order.
- func SearchInt64s(a []int64, x int64) int {
- return sort.Search(len(a), func(i int) bool { return a[i] >= x })
- }
- // UintSlice attaches the methods of sort.Interface to []uint, sorting in increasing order.
- type UintSlice []uint
- func (s UintSlice) Len() int { return len(s) }
- func (s UintSlice) Less(i, j int) bool { return s[i] < s[j] }
- func (s UintSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
- // Sort is a convenience method.
- func (s UintSlice) Sort() {
- sort.Sort(s)
- }
- // SearchUints searches for x in a sorted slice of uints and returns the index
- // as specified by sort.Search. The slice must be sorted in ascending order.
- func SearchUints(a []uint, x uint) int {
- return sort.Search(len(a), func(i int) bool { return a[i] >= x })
- }
- // Uint16Slice attaches the methods of sort.Interface to []uint16, sorting in increasing order.
- type Uint16Slice []uint16
- func (s Uint16Slice) Len() int { return len(s) }
- func (s Uint16Slice) Less(i, j int) bool { return s[i] < s[j] }
- func (s Uint16Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
- // Sort is a convenience method.
- func (s Uint16Slice) Sort() {
- sort.Sort(s)
- }
- // SearchUint16s searches for x in a sorted slice of uint16 and returns the index
- // as specified by sort.Search. The slice must be sorted in ascending order.
- func SearchUint16s(a []uint16, x uint16) int {
- return sort.Search(len(a), func(i int) bool { return a[i] >= x })
- }
- // Uint32Slice attaches the methods of sort.Interface to []uint32, sorting in increasing order.
- type Uint32Slice []uint32
- func (s Uint32Slice) Len() int { return len(s) }
- func (s Uint32Slice) Less(i, j int) bool { return s[i] < s[j] }
- func (s Uint32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
- // Sort is a convenience method.
- func (s Uint32Slice) Sort() {
- sort.Sort(s)
- }
- // SearchUint32s searches for x in a sorted slice of uint32 and returns the index
- // as specified by sort.Search. The slice must be sorted in ascending order.
- func SearchUint32s(a []uint32, x uint32) int {
- return sort.Search(len(a), func(i int) bool { return a[i] >= x })
- }
- // Uint64Slice attaches the methods of sort.Interface to []uint64, sorting in increasing order.
- type Uint64Slice []uint64
- func (s Uint64Slice) Len() int { return len(s) }
- func (s Uint64Slice) Less(i, j int) bool { return s[i] < s[j] }
- func (s Uint64Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
- // Sort is a convenience method.
- func (s Uint64Slice) Sort() {
- sort.Sort(s)
- }
- // SearchUint64s searches for x in a sorted slice of uint64 and returns the index
- // as specified by sort.Search. The slice must be sorted in ascending order.
- func SearchUint64s(a []uint64, x uint64) int {
- return sort.Search(len(a), func(i int) bool { return a[i] >= x })
- }
- // RuneSlice attaches the methods of sort.Interface to []rune, sorting in increasing order.
- type RuneSlice []rune
- func (s RuneSlice) Len() int { return len(s) }
- func (s RuneSlice) Less(i, j int) bool { return s[i] < s[j] }
- func (s RuneSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
- // Sort is a convenience method.
- func (s RuneSlice) Sort() {
- sort.Sort(s)
- }
- // SearchRunes searches for x in a sorted slice of uint64 and returns the index
- // as specified by sort.Search. The slice must be sorted in ascending order.
- func SearchRunes(a []rune, x rune) int {
- return sort.Search(len(a), func(i int) bool { return a[i] >= x })
- }
- // Dedupe returns n, the number of distinct elements in data. The resulting
- // elements are sorted in elements [0, n) or data[:n] for a slice.
- func Dedupe(data sort.Interface) (n int) {
- if n = data.Len(); n < 2 {
- return n
- }
- sort.Sort(data)
- a, b := 0, 1
- for b < n {
- if data.Less(a, b) {
- a++
- if a != b {
- data.Swap(a, b)
- }
- }
- b++
- }
- return a + 1
- }
|